【问题标题】:Accessing UI in a thread在线程中访问 UI
【发布时间】:2010-10-17 02:07:42
【问题描述】:

当我尝试更改 UI 属性(特别是启用)时,我的线程抛出 System.Threading.ThreadAbortException

如何在线程中访问 UI。

【问题讨论】:

    标签: c# multithreading user-interface


    【解决方案1】:

    使用 Win Form 的 BackgroundWorker 类代替手动同步执行如何?

    【讨论】:

      【解决方案2】:

      我假设我们在这里谈论的是 WinForms?您需要有一个线程来管理它 - 创建相关控件的线程。如果您想从不同的线程执行此操作,您可以使用 Control.InvokeRequired 进行检测,那么您应该使用 Control.Invoke 方法将其编组到正确的线程上。谷歌该属性和方法(分别)以了解执行此操作的一些常见模式。

      【讨论】:

      • 在大多数情况下,您也可以安全地使用 BeginInvoke(),除非您想将任何抛出的异常编组回调用线程。
      • InvokeRequired/BeginInvoke 太罗嗦了,IMO。
      【解决方案3】:

      如果您想在非 UI 线程仍在运行时修改 UI,请使用 SynchronizationContext 编组对 UI 线程的调用。否则,请使用BackgroundWorker

      【讨论】:

        【解决方案4】:
        void button1_Click( object sender, EventArgs e ) {
            var thread = new Thread( ParalelMethod );
            thread.Start( "hello world" );
        }
        void ParalelMethod( object arg ) {
           if ( this.InvokeRequired ) {
               Action<object> dlg = ParalelMethod;
               this.Invoke( dlg, arg );
           }
           else {
               this.button1.Text = arg.ToString();
           }
        }
        

        【讨论】:

          【解决方案5】:

          您可以使用 BackgroundWorker,然后像这样更改 UI:

          control.Invoke((MethodInvoker)delegate {
              control.Enabled = true;
          });
          

          【讨论】:

          • 绝对是我遇到的最简单的方法,并且我尝试了多种 UI 更新线程解决方案。得到我的支持。
          • 您因使用最少的文字和显示最清晰的示例/解释而获胜。荣誉
          • 感谢最简单的方法节省我的时间。
          【解决方案6】:

          如果您使用的是 C# 3.5,那么使用扩展方法和 lambdas 来防止从其他线程更新 UI 真的很容易。

          public static class FormExtensions
          {
            public static void InvokeEx<T>(this T @this, Action<T> action) where T : Form
            {
              if (@this.InvokeRequired)
              {
                @this.Invoke(action, @this);
              }
              else
              {
                action(@this);
              }
            }
          }
          

          所以现在您可以在任何表单上使用InvokeEx,并且能够访问不属于Form 的任何属性/字段。

          this.InvokeEx(f => f.label1.Text = "Hello");
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-12-04
            • 2015-06-02
            • 2016-09-17
            • 1970-01-01
            • 1970-01-01
            • 2018-04-27
            相关资源
            最近更新 更多