2013-04-18 55 views
2

我有这样的代码:与UI交谈的线程?

private void buttonStart_Click(object sender, EventArgs e) 
{ 
    Task.Factory.StartNew(() => GeneraListaCartelle()) 
     .ContinueWith(t => GeneraListaCartelleCompletata() 
     , CancellationToken.None 
     , TaskContinuationOptions.None 
     , TaskScheduler.FromCurrentSynchronizationContext()); 
} 

private void GeneraListaCartelle() 
{ 
    try 
    { 
     ... some operation .... 
    } 
    catch (Exception err) 
    { 
     txtErrors.AppendText(err.Message); 
    } 
} 

GeneraListaCartelleCompletata() 
{ 
    ... process finished... 
} 

txtErrors是 “主” 线程(UI)。当我发现错误时,异步线程无法写入UI控件,并且我得到一个invalid cross-thread exception

我可以使用线程内的UI进行对话吗?

+0

您使用的是WPF还是WinForms? – 2013-04-18 07:05:24

+3

什么样的应用程序,winform或WPF,如果WinForm寻找[MethodInvoker](http://msdn.microsoft.com/en-us/library/system.windows.forms.methodinvoker.aspx),为WPF,寻找[Dispatcher.Invoke](http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.invoke.aspx) – Habib 2013-04-18 07:05:42

+0

我正在使用WinForm,对不起;) – markzzz 2013-04-18 07:09:37

回答

3

如果你是靶向然后WinForm应用程序:

try 
    { 
     ... some operation .... 
    } 
catch (Exception err) 
    { 
     if (txtErrors.InvokeRequired) 
     { 
      txtErrors.BeginInvoke(new MethodInvoker(
       delegate { txtErrors.AppendText(err.Message); }) 
       ); 
     } 
    } 
4

如果您正在使用的WinForms,你将需要调用你的方法在UI线程像

catch (Exception err) 
{ 
    if(this.InvokeRequired){ 
     Action<Exception> act = ((ex) => { 
      txtErrors.AppendText(ex.Message); 
     }); 
     this.Invoke(act, new object[] { err }); 
    } 
    else{ 
     txtErrors.AppendText(err.Message); 
    } 
} 

如果您正在使用WPF你将需要

catch (Exception err) 
{ 
    if(this.Dispatcher.CheckAccess()){ 
     txtErrors.AppendText(err.Message); 
    } 
    else { 
      Action<Exception> act = ((ex) => { 
      txtErrors.AppendText(ex.Message); 
      }); 
     this.Dispatcher.Invoke(act, new object[] { err }); 
    } 
} 
2

有来自msdn一个例子:

// This delegate enables asynchronous calls for setting 
// the text property on a TextBox control. 
delegate void SetTextCallback(string text); 

// This method demonstrates a pattern for making thread-safe 
// calls on a Windows Forms control. 
// 
// If the calling thread is different from the thread that 
// created the TextBox control, this method creates a 
// SetTextCallback and calls itself asynchronously using the 
// Invoke method. 
// 
// If the calling thread is the same as the thread that created 
// the TextBox control, the Text property is set directly. 
private void SetText(string text) 
{ 
    // InvokeRequired required compares the thread ID of the 
    // calling thread to the thread ID of the creating thread. 
    // If these threads are different, it returns true. 
    if (this.textBox1.InvokeRequired) 
    { 
     SetTextCallback d = new SetTextCallback(SetText); 
     this.Invoke(d, new object[] { text }); 
    } 
    else 
    { 
     this.textBox1.Text = text; 
    } 
} 
1

集CheckForIllegalCrossThreadCalls假的叫Form_Load事件处理程序

1

拉这一个老项目,我不得不处理从另一个线程更新UI的。也应该为你工作。

delegate void addtoValProg(); 
addtoValProg myDelegate; 

myDelegate = new addtoValProg(invokeControl); 

private void GeneraListaCartelle() 
{ 
    try 
    { 
     //... some operation .... 
    } 
    catch (Exception err) 
    { 
     invokeControl(); 
    } 
} 

private void invokeControl() 
{ 
    if (this.InvokeRequired) 
    { 
     this.Invoke(this.myDelegate); 
    } 
    else 
    { 
     txtErrors.AppendText(err.Message); 
     txtErrors.Update(); 
    } 
}