Process crash when using SerialPort or Socket objects and thread.Abort

The easiest way to demonstrate what this error is all about is to compile and run this code:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.IO.Ports;

namespace ST
{
public class SerialTest
{
public static SerialPort m_port;

public static void ReadFromPort()
{
byte []buffer=new byte[10];
try
{
m_port.Read(buffer, 0, 10);
}
catch (Exception e)
{
Console.WriteLine("Read thread exception: "+e.ToString());
}
}

public static void Main()
{
m_port = new SerialPort("COM1");
m_port.Open();
m_port.ReadTimeout = 100000;

Thread thread = new Thread(new ThreadStart(ReadFromPort));

Console.WriteLine("Starting (read)thread.");
thread.Start();

Thread.Sleep(500);

try
{
Console.WriteLine("Thread Abort.");
thread.Abort();
}
catch (Exception e)
{
Console.WriteLine("Main thread exception: "+e.ToString());
}

Thread.Sleep(500);

Console.WriteLine("Not here.");
Console.ReadLine();
}
}
}

Pay attention on " thread.Abort();" call. The "m_port.Read" has a large timeout and during this rading (that is executin in another thread) we call Abort on that thread. Serial port returns an exception, but that exception cannot be captured and the process is killed.

Seems like the problem is in implementation of the SerialPort class. But it seems to work fine if we close the port before we call thread.Abort. Then the exception can be captured.

Can this issue be resolved so that the thrown exception can be captured Without closing the serial port before aborting the thread.

Thanks.


Answer this question

Process crash when using SerialPort or Socket objects and thread.Abort

  • Gravy

    The SerialPort class generates an exception after you've caught the ThreadAbortException: ObjectDisposedException, "Safe handle has been closed". This exception is not caught (it is not catchable) so your main app dies.

    The stack trace looks like this:
    at Microsoft.Win32.Win32Native.SetEvent(SafeWaitHandle handle)\r\n
    at System.Threading.EventWaitHandle.Set()\r\n
    at System.IO.Ports.SerialStream.AsyncFSCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOverlapped)\r\n
    at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)"

    This problem appears to be very similar to another problem reported for the SerialPort class. Janking a USB serial port emulator while it is opened by a SerialPort instance generates an unrecoverable exception too. I'm guessing here that the BaseStream object gets closed by the abort, which causes an overlapped I/O read to finish, which causes the code to reference the disposed BaseStream object.

    I'd recommend you report this issue at Product Feedback. That's not going to buy you a solution any time soon though. Instead of using a thread, consider using the DataReceived event to implement the reading...


  • Process crash when using SerialPort or Socket objects and thread.Abort