Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在线程中访问UI_C#_Multithreading_User Interface - Fatal编程技术网

C# 在线程中访问UI

C# 在线程中访问UI,c#,multithreading,user-interface,C#,Multithreading,User Interface,当我尝试更改UI属性(特别是启用)时,我的线程抛出System.Threading.ThreadAbortException 如何在线程中访问UI。使用Win Form的BackgroundWorker类而不是手动实现AD同步怎么样?我想我们这里讨论的是WinForms?您需要有一个单独的线程来管理它,即创建该控件的线程。如果要从不同的线程执行此操作,可以使用Control.InvokeRequired进行检测,那么应该使用Control.Invoke方法将其整理到正确的线程上。在执行此操作时,

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


如何在线程中访问UI。

使用Win Form的BackgroundWorker类而不是手动实现AD同步怎么样?

我想我们这里讨论的是WinForms?您需要有一个单独的线程来管理它,即创建该控件的线程。如果要从不同的线程执行此操作,可以使用Control.InvokeRequired进行检测,那么应该使用Control.Invoke方法将其整理到正确的线程上。在执行此操作时,分别用谷歌搜索一些常见模式的属性和方法。

如果要在非UI线程仍在运行时修改UI,请使用
SynchronizationContext
封送对UI线程的调用。否则,请使用
BackgroundWorker

void按钮1\u单击(对象发送者,事件参数e){
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();
   }
}
var线程=新线程(并行方法); thread.Start(“helloworld”); } 无效并行方法(对象参数){ if(this.invokererequired){ 动作dlg=平行法; 调用(dlg,arg); } 否则{ this.button1.Text=arg.ToString(); } }
您可以使用BackgroundWorker,然后像这样更改UI:

control.Invoke((MethodInvoker)delegate {
    control.Enabled = true;
});
如果您使用的是C#3.5,那么使用扩展方法和lambda来防止其他线程更新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);
    }
  }
}

在大多数情况下,您也可以安全地使用BeginInvoke(),除非您想将任何抛出的异常封送回调用线程。
invokererequired/BeginInvoke
太冗长了,我觉得这绝对是我遇到的最简单的方法,我也尝试过许多UI更新线程的解决方案。我投了赞成票。你用最少的文字和最清晰的例子/解释获胜。库多斯:这是节省我时间的最简单的方法。
this.InvokeEx(f => f.label1.Text = "Hello");