• <i id='ROLah'><tr id='ROLah'><dt id='ROLah'><q id='ROLah'><span id='ROLah'><b id='ROLah'><form id='ROLah'><ins id='ROLah'></ins><ul id='ROLah'></ul><sub id='ROLah'></sub></form><legend id='ROLah'></legend><bdo id='ROLah'><pre id='ROLah'><center id='ROLah'></center></pre></bdo></b><th id='ROLah'></th></span></q></dt></tr></i><div id='ROLah'><tfoot id='ROLah'></tfoot><dl id='ROLah'><fieldset id='ROLah'></fieldset></dl></div>
    <legend id='ROLah'><style id='ROLah'><dir id='ROLah'><q id='ROLah'></q></dir></style></legend>
        <bdo id='ROLah'></bdo><ul id='ROLah'></ul>

      <tfoot id='ROLah'></tfoot>

      1. <small id='ROLah'></small><noframes id='ROLah'>

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

        What causes my UI to freeze when closing a serial port?(关闭串行端口时,是什么导致我的 UI 冻结?)

          <tbody id='cyj9x'></tbody>
        • <tfoot id='cyj9x'></tfoot>
          <i id='cyj9x'><tr id='cyj9x'><dt id='cyj9x'><q id='cyj9x'><span id='cyj9x'><b id='cyj9x'><form id='cyj9x'><ins id='cyj9x'></ins><ul id='cyj9x'></ul><sub id='cyj9x'></sub></form><legend id='cyj9x'></legend><bdo id='cyj9x'><pre id='cyj9x'><center id='cyj9x'></center></pre></bdo></b><th id='cyj9x'></th></span></q></dt></tr></i><div id='cyj9x'><tfoot id='cyj9x'></tfoot><dl id='cyj9x'><fieldset id='cyj9x'></fieldset></dl></div>

          • <small id='cyj9x'></small><noframes id='cyj9x'>

                <bdo id='cyj9x'></bdo><ul id='cyj9x'></ul>

                <legend id='cyj9x'><style id='cyj9x'><dir id='cyj9x'><q id='cyj9x'></q></dir></style></legend>

                1. 本文介绍了关闭串行端口时,是什么导致我的 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 冻结?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  Multicast delegate weird behavior in C#?(C# 中的多播委托奇怪行为?)
                  Parameter count mismatch with Invoke?(参数计数与调用不匹配?)
                  How to store delegates in a List(如何将代表存储在列表中)
                  How delegates work (in the background)?(代表如何工作(在后台)?)
                  C# Asynchronous call without EndInvoke?(没有 EndInvoke 的 C# 异步调用?)
                  Delegate.CreateDelegate() and generics: Error binding to target method(Delegate.CreateDelegate() 和泛型:错误绑定到目标方法)

                    <legend id='4s2Ku'><style id='4s2Ku'><dir id='4s2Ku'><q id='4s2Ku'></q></dir></style></legend>
                      <bdo id='4s2Ku'></bdo><ul id='4s2Ku'></ul>

                      <small id='4s2Ku'></small><noframes id='4s2Ku'>

                              <tbody id='4s2Ku'></tbody>
                          • <tfoot id='4s2Ku'></tfoot>
                            <i id='4s2Ku'><tr id='4s2Ku'><dt id='4s2Ku'><q id='4s2Ku'><span id='4s2Ku'><b id='4s2Ku'><form id='4s2Ku'><ins id='4s2Ku'></ins><ul id='4s2Ku'></ul><sub id='4s2Ku'></sub></form><legend id='4s2Ku'></legend><bdo id='4s2Ku'><pre id='4s2Ku'><center id='4s2Ku'></center></pre></bdo></b><th id='4s2Ku'></th></span></q></dt></tr></i><div id='4s2Ku'><tfoot id='4s2Ku'></tfoot><dl id='4s2Ku'><fieldset id='4s2Ku'></fieldset></dl></div>