0

我正在开发一个与串口相关的应用程序。在使用DataReceived事件时,SerialPort我需要使用接收到的字节更新文本框:

private void Connection_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    ledReceive.On = true;

    var data = Connection.ReadExisting();

    _readBuffer.Add(data);
    Invoke(new EventHandler(AddReceivedPacketToTextBox));       
}

所以我Invoke用来更新文本框。但是有一个大问题。当我尝试关闭连接时,我的 UI 被冻结,我认为这是Invoke因为可能正在做某事。

一位朋友说我应该使用RequiredInvoke,但我不知道他到底是什么。如何在不弄乱调用和 UI 线程的情况下关闭连接?

这是我的关闭方法:

private void DisconnectFromSerialPort()
{
    if (Connection != null && Connection.IsOpen)
    {
        Connection.Close();
        _receivedPackets = 0; //reset received packet count
    }
}
4

1 回答 1

1

我不完全确定,但我猜想当您关闭连接时,更新 UI 的线程会被删除,这可以解释为什么它会冻结。但是如果不深入研究您的所有代码,我无法确定。

如果尝试访问您的元素的线程不是您的 UI 的原生线程,则 InvokeRequired 返回 true。或者,如果您更喜欢 MS 解释:

    // Summary:
    //     Gets a value indicating whether the caller must call an invoke method when
    //     making method calls to the control because the caller is on a different thread
    //     than the one the control was created on.
    //
    // Returns:
    //     true if the control's System.Windows.Forms.Control.Handle was created on
    //     a different thread than the calling thread (indicating that you must make
    //     calls to the control through an invoke method); otherwise, false.

和一个基本的实现:

    public void ReceiveCall()
    {
        if (this.InvokeRequired)
        {
            this.Invoke(new CallDelegate(ReceiveCall), new object[] { });
            return; // Important to not continue on this method.
        }

        // Whatever else this function is suppose to do when on the correct thread.
    }

Invoke 应该是您的函数所做的第一件事,以防止该线程深入您的 UI。现在,如果连接本身被确定在 UI 线程的边界内,它可能不会触发“InvokeRequired”。防止这种情况发生的一种方法是手动创建一个线程来更新未绑定到您的连接的 UI。

我在更新多个 UI 元素的渲染时遇到了类似的问题。时钟可以正常工作,但会“挂起”,直到所有 UI 都完成渲染,如果有很多 UI,这意味着它会跳过下一个滴答声。

     Thread updateUI = new Thread(updateUIDelegate);
     updateUI.Start();

这样,我的时钟(或您的连接)将启动一个独立线程,该线程自行完成其工作。您可能还需要检查 Monitor 类或 lock 关键字,以防止使用相同变量的线程或多个线程发生冲突。

编辑:或者您可以阅读很棒的答案,这可能比我的更有意义:关闭串行端口时导致我的 UI 冻结的原因是什么?

于 2012-10-16T12:02:26.467 回答