在加入线程之后或加入线程之前关闭端口?

时间:2013-09-09 16:38:44

标签: c# thread-safety serial-port

我想从端口获取信号并且我使用这些函数来接收数据,但我有时会在线路上获得此异常thread.join():

System.IO.IOException未处理

Message =“由于线程退出或应用程序请求,I / O操作已中止。

当我插入一个断点并对其进行调试时,它会一直正常,直到在线thread.join()然后UI停止并且没有发生。

当我在发布模式下运行我的程序时,它工作正常,但问题出在调试模式,出了什么问题以及如何解决这个问题?

日Thnx。

    public SignalReader()
    {
        thread = new Thread(new ThreadStart(ThreadMain));
    }
    public void Start(string portName, int rate)
    {
        Stop();
        try
        {
            port = new SerialPort(portName, rate);
            port.Open();
        }
        catch
        {
            ;
        }
        thread.Start();
    }
    public void Stop()
    {

        try
        {
            if (port != null)
            {
                if (port.IsOpen) port.Close();
                if (thread.IsAlive) thread.Join();
                port.Dispose();
                port = null;
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("4:" + ex.ToString());
        }
    }

当我交换关闭端口和加入线程的顺序时:

...
thread.Join();
port.Close();
...

同样的故事存在。

2 个答案:

答案 0 :(得分:1)

您正在使用地板垫,在使用时关闭端口。最典型的是在SerialPort.Read()调用中。所以,是的,那个电话会失败,再也没有地垫了。缺少的是一个catch块,它捕获该异常并让线程优雅地结束。并完成Join()调用。

这样做并不完全不寻常,只要你能确保线程在这样的Read调用上实际阻塞。这通常不是很难保证。但肯定会担心在Release版本中没有获得该异常,这是不正常的。使用调试器的Debug + Window + Threads来查看该工作线程中发生了什么。

所以只需添加所需的try / catch来解决您的问题。使用SerialPort.DataReceived事件是一种完全不同的方法。根本没有清理,只是将线程的IsBackground属性设置为true,这样当程序终止时它自动死掉也是一个非常可接受的解决方案。

答案 1 :(得分:0)

您收到的错误是因为您正在使用的Stop():

public void Start(string portName, int rate)
    {
        Stop();
        try
        {
            port = new SerialPort(portName, rate);
            port.Open();
        }
        catch
        {
            ;
        }
        thread.Start();
    }

应用程序已经做了一些事情,当你调用它时它会关闭一个正在使用的端口。

尝试删除它,如果端口未关闭,您将在Start方法中获得异常。它可以让您更好地了解此错误的来源。你也可以粘贴使用这些方法的部分代码吗?