I am developing a .NET 4.0 WPF application in C# that controls a motor via RS232. I am having problems when exiting my application that the application sometimes deadlocks when closing the comport.
After some research on the internet I noticed this was a common problem and that using BeginInvoke in the DataReceivedEvent or closing the serialport in a different thread should solve the problem.
The problem with those workarounds are that.
1. I dont use the DataReceiveEvent.
2. closing the serialport in another thread doesnt make any difference. What happens is that the GUI shutsdown but you can see in the TaskManager that the process is still running.
Other things I have tried is:
- Not closing the serialport and just exiting the application. This successfully closes the application and process but the serialport is still blocked, and to unblock the serialport I need to restart the computer.
- Sleeping a couple of seconds before and after I close the serialport.
- Having the application be a WinForms app. instead of WPF. No difference in the deadlock between the two.
The computer I run the program on uses com ports that are mounted on the motherboard and have Microsoft drivers.
And now for some code:
Window_Closing event looks like this:
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
window.Closing -= Window_Closing;
Thread CloseDown = new Thread(new ThreadStart(server.Dispose)); //Closes serialport everything in another thread to avoid hang on serialport close.
CloseDown.Start();
}
Where server is the object that manages the serialport. And Dispose calls the serialport close function.
Serialport close function:
public void Close()
{
DebugLog.Write(3, "-->MacCommSerialPort.Close");
_com.Close();
DebugLog.Write(3, "<--MacCommSerialPort.Close");
}
Serialport settings:
_com = new SerialPort(portNumber);
_com.BaudRate = 19200;
_com.Parity = Parity.None;
_com.DataBits = 8;
_com.Encoding = Encoding.GetEncoding("Windows-1252");
_com.StopBits = StopBits.One;
_com.RtsEnable = false;
_com.DtrEnable = false;
_com.WriteTimeout = 400;
_com.ReadTimeout = 1000;
I just happened to look at your code and guess you should use the AutoThreadRest event before closing your GUI.
and inside the server.Dispose method after you are done disposing the connection add this below line of code.