关闭串行端口时,是什么导致我的 UI 冻结?

What causes my UI to freeze when closing a serial port?(关闭串行端口时,是什么导致我的 UI 冻结?)
本文介绍了关闭串行端口时,是什么导致我的 UI 冻结?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am working on a serial port related application. While using DataReceived event of SerialPort I need to update a textbox with the received bytes:

private void Connection_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    var data = Connection.ReadExisting();
    _readBuffer.Add(indata);

    Invoke(new EventHandler(AddReceivedPacketToTextBox));       
}

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

So I use Invoke to update the textbox. But there is a big problem. When I try to close connection, my UI gets freezed, I think this is becase Invoke is doing somehing perhaps.

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

A friend said I should use RequiredInvoke, but I have no idea what he ment really. How can I close the connection without messing up the invoke and UI thread?

这是我的关闭方法:

private void DisconnectFromSerialPort()
{
    if (Connection != null && Connection.IsOpen)
    {
        Connection.Close();            
    }
}

更新

正如汉斯所说,我将 Invoke 更改为 BeginInvoke 但现在更糟了,我的应用程序由于 InvalidOperationException 而停止工作,因为集合 _readBuffer 已修改(VS 中的细节是这样说的)

As Hans said I changed Invoke to BeginInvoke but now its a bit worse, my application stops working due to InvalidOperationException because the collection _readBuffer was modified (Thats what the detail says in VS)

这是我将文本添加到文本框的代码:

Here is my code for adding text to textbox:

private void AddReceivedPacketToTextBox(object sender, EventArgs e)
{

    foreach (var i in _readBuffer)
        tbIn.Text += string.Format("{0:X2} ", i);

    tbIn.Text += Environment.NewLine;

    ScrollToBottom(tbIn);

    label4.Text = _receivedPackets.ToString();
    _receivedPackets++;

    _readBuffer.Clear(); //Possibly because clearing collection gets out of sync with BeginInvoke??         
}

第二次更新

我仍然有问题,将 Invoke() 更改为 BeginInvoke 没有帮助.我还尝试添加断开连接以形成关闭事件 nu 成功...每当我关闭我的表单时,它都会获得库存(我的意思是它的父表单,因为这个可以访问串行端口的表单正在从另一个表单调用.

I still have the problem, changing the Invoke() to BeginInvoke didn;t help. I also tried to add disconnect to form closing event nu success...anytime I close my form it gets stock (I mean its parent form, because this form that has access to serialport is being called from another form`.

我的意思是我发现 UI 仅在 2 种情况下被锁定:如果我为调用 Connection.Close() 的按钮计时,如果我尝试关闭表单,父表单将抛出一些对象被释放的异常.

I mean I figured out that the UI gets locked only in 2 cases: If I clock a button which calls Connection.Close() also if I try to close the form, the parent form will throw exception that some objects are disposed.

我从父表单中这样调用串行表单:

I call the serial form like this from the parent form:

public DebugForm DebugForm;

private void button1_Click(object sender, EventArgs e)
{
    if (DebugForm != null)
    {
        DebugForm.BringToFront();
        return;
    }

    DebugForm = new DebugForm();
    DebugForm.StartPosition = FormStartPosition.CenterScreen;
    DebugForm.Closed += delegate
                             {
                                 WindowState = FormWindowState.Normal;
                                 DebugForm = null;
                             };

    DebugForm.Show();
    WindowState = FormWindowState.Minimized; 
}

这会是问题吗?!

推荐答案

这个问题可以通过添加定时器来解决:

The problem could be solved by adding a timer:

  bool formClosing = false;
    private void Connection_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
      if (formClosing) return;
      _buffer = Connection.ReadExisting();
      Invoke(new EventHandler(AddReceivedPacketToTextBox));
    }
    protected override void OnFormClosing(FormClosingEventArgs e)
    {
      base.OnFormClosing(e);
      if (formClosing) return;
      e.Cancel = true;
      Timer tmr = new Timer();
      tmr.Tick += Tmr_Tick;
      tmr.Start();
      formClosing = true;
    }
    void Tmr_Tick(object sender, EventArgs e)
    {
      ((Timer)sender).Stop();
      this.Close();
    }

感谢 MSDN<的 JohnWein/a>

Thanks to JohnWein from MSDN

这篇关于关闭串行端口时,是什么导致我的 UI 冻结?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)