I'm working on a C# UWP APP and I need to communicate with many devices using an USB port as Serial Port. After that I will convert the communication to RS485 to communicate with the other devices. Until now, I have create a class that will make all comunications between my devices and I can sent a trama between my devices.
My problem at this point is that after sending some startup frames, the application changes the page and from that moment gives me the following exception in my ReadAsync method:
**
System.Exception occurred HResult=-2147023901 Message=The I/O operation was canceled due to a module output or an application request. (Exception from HRESULT: 0x800703E3) Source=mscorlib
StackTrace: at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at DrDeliver.CComm.d__31.MoveNext() InnerException:
**
I already have this problem for a few days and I can't get over it.
I wonder if anyone can figure out where the problem is.
Another question I would like to ask is if anyone knows of any method that allows me to make this communication synchronously.
UPDATE 1 The entire class for communicatons:
public class CComm : IDisposable
{
EventLogDB _eldb = new EventLogDB();
ParameterDB _pdb = new ParameterDB();
cParameter _cParam = new cParameter();
DataReader _dataReaderObject = null;
private DispatcherTimer mTimer;
private int num;
public bool FlagComm { set; get; }
public static string InBuffer { set; get; }
public bool busyFlag = false;
public CancellationTokenSource _readCancellationTokenSource = new CancellationTokenSource();
private DeviceInformationCollection DeviceInformation { set; get; }
private static SerialDevice SerialPort { set; get; }
// Define a delegate
public delegate void CheckReadEventHandler(object source, EventArgs args);
// Define an event based on that delegate
public event CheckReadEventHandler CheckRead;
// Raise an event
protected virtual void OnChecRead()
{
CheckRead?.Invoke(this, EventArgs.Empty);
}
private async Task OpenComm()
{
try
{
busyFlag = true;
//_cParam = _pdb.getParameters();
string selectedPortId = null;
string aqs = SerialDevice.GetDeviceSelector();
DeviceInformation = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(aqs);
foreach (var devInfo in DeviceInformation)
{
if (devInfo.Name == "USB-RS485 Cable")
{
selectedPortId = devInfo.Id;
}
}
if (selectedPortId != null)
{
SerialPort = await SerialDevice.FromIdAsync(selectedPortId);
if (SerialPort != null)
{
SerialPort.ReadTimeout = TimeSpan.FromMilliseconds(1500);
SerialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000);
SerialPort.BaudRate = 9600;
SerialPort.Parity = SerialParity.None;
SerialPort.StopBits = SerialStopBitCount.One;
SerialPort.DataBits = 8;
FlagComm = true;
}
else
{
var status = DeviceAccessInformation.CreateFromId(selectedPortId).CurrentStatus;
FlagComm = false;
_eldb.attachEvent("E1002", "Starting Comunication Failed: " + status);
//ContentDialog noSerialDevice = new ContentDialog()
//{
// Title = "No Serial Connection",
// Content = "Check connection and try again. App Closing.",
//};
//await noSerialDevice.ShowAsync();
//this.Dispose();
}
InitTool();
await ActivateListen();
busyFlag = false;
}
}
catch (Exception ex)
{
_eldb.attachEvent("E1cC", ex.Message);
}
}
private async Task Listen()
{
try
{
if (SerialPort != null)
{
busyFlag = true;
_dataReaderObject = new DataReader(SerialPort.InputStream);
await ReadAsync(_readCancellationTokenSource.Token);
busyFlag = false;
}
}
catch (Exception ex)
{
}
}
//using (var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(1000)))
//{
// await dataReaderObject.LoadAsync(1024).AsTask(cts.Token);
//}
private async Task ReadAsync(CancellationToken cancellationToken)
{
busyFlag = true;
const uint readBufferLength = 1024; // only when this buffer would be full next code would be executed
var loadAsyncTask = _dataReaderObject.LoadAsync(readBufferLength).AsTask(cancellationToken); // Create a task object
_dataReaderObject.InputStreamOptions = InputStreamOptions.ReadAhead;
var bytesRead = await loadAsyncTask; // Launch the task and wait until buffer would be full
if (bytesRead > 0)
{
InBuffer += _dataReaderObject.ReadString(bytesRead);
OnChecRead();
}
busyFlag = false;
}
private async void WriteComm(string str2Send)
{
using (var dataWriter = new DataWriter(SerialPort.OutputStream))
{
dataWriter.WriteString(str2Send);
await dataWriter.StoreAsync();
dataWriter.DetachStream();
}
}
private async Task ActivateListen()
{
while (FlagComm)
{
await Listen();
}
}
private void dispatcherTimer_Tick(object sender, object e)
{
_eldb.attachEvent("SYSTEM", "Checking ADDR: " + num);
SendComm(num++, 5);
if (num == 5)
{
mTimer.Stop();
_eldb.attachEvent("SYSTEM", "Modules Checking Finished.");
busyFlag = false;
}
}
public void InitTool()
{
busyFlag = true;
_eldb.attachEvent("SYSTEM", "Setting Parameters.");
// Get Parameters
if (_pdb.GetParameters() == null)
{
// Set Default Parameters
_cParam.SetParam();
// Insert Default parameters in database
_pdb.Insert(_cParam);
// Update Parameters Object
_cParam = _pdb.GetParameters();
}
else
{
// Update Parameters Object
_cParam = _pdb.GetParameters();
}
// Check Addresses in Line
_eldb.attachEvent("SYSTEM", "Start Verifiyng.");
num = 0;
mTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(4000) };
mTimer.Tick += dispatcherTimer_Tick;
mTimer.Start();
}
public async void StartSerialComm()
{
try
{
await OpenComm();
}
catch (Exception ex)
{
_eldb.attachEvent("E7cC", ex.Message);
}
}
public void SendComm(params int[] list)
{
try
{
_cParam = _pdb.GetParameters();
string toSend = "";// = "A" + list[0] + "#";
switch (list[1])
{
case 0:
// Send Initialazation command
toSend = "#@" + list[0] + "@" + list[1] + "@#";
break;
case 1:
// List of parameters (minPower, maxPower, ramPercent, initSpeed)
toSend = "#@" + list[0] + "@" + list[1] + "@" + _cParam.minPower + "@" +
_cParam.maxPower + "@" + _cParam.percRamp + "@" + _cParam.initSpeed + "@#";
break;
case 2:
// Send Status Request
toSend = "#@" + list[0] + "@" + list[1] + "@#";
break;
case 3:
// Send a move Request
toSend = "#@" + list[0] + "@" + list[1] + "@" + list[2] + "@#";
break;
case 4:
// Send a Error Request
toSend = "#@" + list[0] + "@" + list[1] + "@#";
break;
case 5:
// Send a start check
toSend = "#@" + list[0] + "@" + list[1] + "@#";
break;
default:
_eldb.attachEvent("E1004", "Wrong Function Command.");
break;
}
if (toSend != "")
{
WriteComm(toSend);
}
else
{
_eldb.attachEvent("E1003", "Wrong String comunication.");
}
}
catch (Exception ex)
{
_eldb.attachEvent("E8cC", ex.Message);
}
}
public void Dispose()
{
try
{
if (SerialPort == null) return;
FlagComm = false;
SerialPort.Dispose();
SerialPort = null;
if (_dataReaderObject == null) return;
_readCancellationTokenSource.Cancel();
_readCancellationTokenSource.Dispose();
}
catch (Exception ex)
{
_eldb.attachEvent("E6cC", ex.Message);
}
}
}
Main Page:
public sealed partial class MainPage : Page
{
CComm _cC = new CComm();
EventLogDB _eldb = new EventLogDB();
procTrama _cProcTrama = new procTrama();
private DispatcherTimer mTimer;
public MainPage()
{
try
{
InitializeComponent();
// Get the application view title bar
ApplicationViewTitleBar appTitleBar = ApplicationView.GetForCurrentView().TitleBar;
// Make the title bar transparent
appTitleBar.BackgroundColor = Colors.Transparent;
// Get the core appication view title bar
CoreApplicationViewTitleBar coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
/*
ExtendViewIntoTitleBar
Gets or sets a value that specifies whether this title
bar should replace the default window title bar.
*/
// Extend the core application view into title bar
coreTitleBar.ExtendViewIntoTitleBar = true;
mTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(5000) };
mTimer.Tick += dispatcherTimer_Tick;
mTimer.Start();
_eldb.attachEvent("S1027", "Init Started...");
// Start comunication
_cC.StartSerialComm();
// Reference for CheckRead Event
_cC.CheckRead += OnCheckRead;
}
catch (Exception ex)
{
_eldb.attachEvent("MainP", ex.Message);
}
}
private void dispatcherTimer_Tick(object sender, object e)
{
if (!_cC.busyFlag)
{
Frame.Navigate(typeof(InitPage), null);
mTimer.Stop();
}
}
public void OnCheckRead(object source, EventArgs e)
{
try
{
if (CComm.InBuffer == null) return;
_cProcTrama.ProcessTrama(CComm.InBuffer);
CComm.InBuffer = "";
}
catch (Exception ex)
{
_eldb.attachEvent("OnCheckRead: ", ex.Message);
}
}
}
INIT Page:
public partial class InitPage : Page
{
CComm _cC = new CComm();
EventLogDB _eldb = new EventLogDB();
procTrama _cProcTrama = new procTrama();
public InitPage()
{
this.InitializeComponent();
_eldb.attachEvent("S1000", "System Started.");
// Reference for CheckRead Event
_cC.CheckRead += OnCheckRead;
}
private void button_Click(object sender, RoutedEventArgs e)
{
_eldb.attachEvent("S1001", "Login Activated.");
Frame.Navigate(typeof(Page1), null);
}
public void OnCheckRead(object source, EventArgs e)
{
if (CComm.InBuffer == null) return;
_eldb.attachEvent("OnCheckRead: ", CComm.InBuffer);
_cProcTrama.ProcessTrama(CComm.InBuffer);
}
}
Login Page where i more frequently the error occur:
public sealed partial class Page1 : Page
{
private CComm _cC = new CComm();
private procTrama _cProcTrama = new procTrama();
EventLogDB _eldb = new EventLogDB();
public Page1()
{
this.InitializeComponent();
// Reference for CheckRead Event
_cC.CheckRead += OnCheckRead;
user = null;
pass = null;
user_pass = 0;
}
private const int userLimit = 5;
private const int passLimit = 5;
private const char passChar = '*';
public string user
{
get; set;
}
public string pass
{
get; set;
}
public int user_pass
{
get; set;
}
private void execute(char val)
{
string aux = null;
if (user_pass == 1)
{
if (user == null)
user = val.ToString();
else
{
if (user.Length <= userLimit)
user = user + val;
}
userBtn.Content = user;
}
else
{
if (user_pass == 2)
{
if (pass == null)
pass = val.ToString();
else
{
if (pass.Length <= passLimit)
pass = pass + val;
}
for (int i = 0; i < pass.Length; i++)
aux = aux + passChar;
passBtn.Content = aux;
}
}
}
private void key1Btn_Click(object sender, RoutedEventArgs e)
{
execute('1');
}
private void key2Btn_Click(object sender, RoutedEventArgs e)
{
execute('2');
}
private void key3Btn_Click(object sender, RoutedEventArgs e)
{
execute('3');
}
private void key4Btn_Click(object sender, RoutedEventArgs e)
{
execute('4');
}
private void key5Btn_Click(object sender, RoutedEventArgs e)
{
execute('5');
}
private void key6Btn_Click(object sender, RoutedEventArgs e)
{
execute('6');
}
private void key7Btn_Click(object sender, RoutedEventArgs e)
{
execute('7');
}
private void key8Btn_Click(object sender, RoutedEventArgs e)
{
execute('8');
}
private void key9Btn_Click(object sender, RoutedEventArgs e)
{
execute('9');
}
private void key0Btn_Click(object sender, RoutedEventArgs e)
{
execute('0');
}
private void keyEntrarBtn_Click(object sender, RoutedEventArgs e)
{
if (pass == "123" && user == "123")
{
_eldb.attachEvent("S1002", "User Login: " + user);
Frame.Navigate(typeof(Page2), null);
}
user_pass = 0;
passBtn.Content = "Insirir Código";
userBtn.Content = "Inserir Utilizador";
}
private void keyApagarBtn_Click(object sender, RoutedEventArgs e)
{
pass = null;
user = null;
user_pass = 0;
passBtn.Content = "Inserir Código";
userBtn.Content = "Inserir Utilizador";
_eldb.attachEvent("S1003", " User data cleared.");
}
private void userBtn_Click(object sender, RoutedEventArgs e)
{
user_pass = 1;
userBtn.Content = "";
_eldb.attachEvent("S1004", "User button clicked.");
}
private void passBtn_Click(object sender, RoutedEventArgs e)
{
user_pass = 2;
passBtn.Content = "";
_eldb.attachEvent("S1005", "Pass button clicked.");
}
private void exitBtn_Click(object sender, RoutedEventArgs e)
{
_eldb.attachEvent("S1006", "Page1 exit button clicked.");
Frame.Navigate(typeof(InitPage), null);
}
public void OnCheckRead(object source, EventArgs e)
{
try
{
if (CComm.InBuffer == null) return;
_eldb.attachEvent("OnCheckRead: ", CComm.InBuffer);
_cProcTrama.ProcessTrama(CComm.InBuffer);
}
catch (Exception ex)
{
_eldb.attachEvent("OnCheckRead: ", ex.Message);
}
}
}
User contributions licensed under CC BY-SA 3.0