【发布时间】:2010-10-17 02:07:42
【问题描述】:
当我尝试更改 UI 属性(特别是启用)时,我的线程抛出 System.Threading.ThreadAbortException
如何在线程中访问 UI。
【问题讨论】:
标签: c# multithreading user-interface
当我尝试更改 UI 属性(特别是启用)时,我的线程抛出 System.Threading.ThreadAbortException
如何在线程中访问 UI。
【问题讨论】:
标签: c# multithreading user-interface
使用 Win Form 的 BackgroundWorker 类代替手动同步执行如何?
【讨论】:
我假设我们在这里谈论的是 WinForms?您需要有一个线程来管理它 - 创建相关控件的线程。如果您想从不同的线程执行此操作,您可以使用 Control.InvokeRequired 进行检测,那么您应该使用 Control.Invoke 方法将其编组到正确的线程上。谷歌该属性和方法(分别)以了解执行此操作的一些常见模式。
【讨论】:
InvokeRequired/BeginInvoke 太罗嗦了,IMO。
如果您想在非 UI 线程仍在运行时修改 UI,请使用 SynchronizationContext 编组对 UI 线程的调用。否则,请使用BackgroundWorker。
【讨论】:
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();
}
}
【讨论】:
您可以使用 BackgroundWorker,然后像这样更改 UI:
control.Invoke((MethodInvoker)delegate {
control.Enabled = true;
});
【讨论】:
如果您使用的是 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");
【讨论】: