I\'ve built a C# application which reads and writes data from a serial port. The device connected to the serial port is a FTDI USB to serial converter which communicates to hard
I use intensively SerialPort class to communicate continuously with PLCs through USB Adapters for months without any break. So I cannot agree who says SerialPort .NET class does not work. Try to insert creation of class into thread, here is a sample of code with BackgroundWorker.
void ThreadEngine_DoWork(object sender, DoWorkEventArgs e)
{
// Do not access the form's BackgroundWorker reference directly.
// Instead, use the reference provided by the sender parameter.
BackgroundWorker objBackgroundWorker = sender as BackgroundWorker;
try
{
mSerialPort = new SerialPort(GetPortName(mPortName), DefaultBaudRate, Parity.Even, 7, StopBits.Two);
mSerialPort.Open();
objBackgroundWorker.ReportProgress(0);
while (objBackgroundWorker.CancellationPending == false)
{
if (IOScanner(objBackgroundWorker, false) == true)
{
ScannerStationData();
IsReady = true;
IsError = false;
}
else
{
IsReady = false;
IsError = true;
}
Thread.Sleep(1);
}
// Performs last scan before thread closing
if (objBackgroundWorker.CancellationPending == true)
{
IOScanner(objBackgroundWorker, true);
}
mSerialPort.Close();
mSerialPort = null;
e.Result = null;
}
catch (Exception objErr)
{
string sMessage = string.Format("PlcService.ThreadEngine_DoWork Err={0}", objErr.Message);
mLogSysService.AddItem(sMessage);
IsError = true;
}
}
Method IOScanner calls other methods for to communicate like following one.
protected bool WriteDMWord(int iAddress, int[] aryValues)
{
bool bRetValue = true;
try
{
mSerialPort.NewLine = "\r";
mSerialPort.ReadTimeout = DefaultTimeout;
string sTxData = HostLinkProtocol.BuildWriteDMWord(iAddress, aryValues);
mSerialPort.WriteLine(sTxData);
string sRxData = string.Empty;
sRxData = mSerialPort.ReadLine();
if (HostLinkProtocol.ParseWriteDMWord(sRxData) == true)
{
bRetValue = true;
}
}
catch (Exception objErr)
{
Console.WriteLine("WriteDMWord [{0}]", objErr.Message);
bRetValue = false;
}
return bRetValue;
}
In my experience 9 times out of 10 this happens when another thread (terminated or not) doesn't have exclusive access to the hardware port.
Try writing a wrapper for the port operations, most importantly the open/closing of it, using SyncLock. https://msdn.microsoft.com/en-us/library/3a86s51t.aspx
On a similar note, I would generally consider try/catches controlling hardware a bad practice, unless there's adequate exception handling.
The reason (which could apply here) is that in the case where an exception is thrown the hardware will lock, and what is worse, the exception will mask the true cause of the error(s).
In the code above I see output of messages in the style
DebugPrint(ex.Message);
it would be quite better to do this like
DebugPrint(ex.tostring());
as this will also export the stack trace in the exception.
What I would do is implement an exception logger that writes those exceptions to a (time stamped) text file somewhere in the computer this is running. Following on the exception data logged (along with all pertinent information) can lead to a better understanding why exactly this happens.
I use a FTDI USB, and I communicate with it on Serial .net class, sometimes on WindowsXp I have this kind of exception, I solve it with devcon.exe, I perform disable and enable and the error did not appears.