2

我有 ac# .NET winforms 应用程序进行此异步调用:

simpleDelegate.BeginInvoke(null, null);

代表正在调用我的函数,并且一切正常。问题是,在工作线程上的函数完成后,我需要主线程来更新我的 winform 上的一些控件。如果工作线程试图更新这些控件,.NET 就会崩溃。但我需要主线程保持对用户操作的响应,然后仅在工作线程完成调用异步函数后调用我的函数 UpdateFormAfterServerCall()。

如果您能给我一个简洁的代码示例,而不是抽象地解释如何做到这一点,我将不胜感激。我已经阅读了一百个解释,只是无法正确地将它们连接在一起。

注意:在 BeginInvoke 之前我有:

simpleDelegate = new MethodInvoker(CallServer);
4

4 回答 4

3

如果要更新由另一个线程拥有的 GUI,请从不同的线程使用MethodInvoker

if(control.InvokeRequired)
control.Invoke( (MethodInvoker) ( ()=> updating_function() ) );
else
updating_function();
于 2012-06-08T13:53:55.197 回答
1

ControlForm也是 a Control)有一个Invoke方法,您可以从任何线程调用它以在 GUI 线程上执行代码。

此外,Control它还有一个方便的InvokeRequired属性,可以通知您是否已经在 GUI 线程上。例如,您可以在表单中创建以下方法:

public class MyForm
{
    // ...
    public void UpdateMe()
    {
        if (InvokeRequired)
        {
            Invoke(new Action(UpdateMe));
            return;
        }

       // Code to update the control, guaranteed to be on the GUI thread
    }
}
于 2012-06-08T13:47:10.850 回答
1

您可以使用BackgroundWorker

BackgroundWorker bw = new BackgroundWorker();

string result = null;

bw.DoWork += (s, e) =>
{
    // Executes on background thread.
    // UI remains responsive to user activity during this time.
    result = CallServer();
};

bw.RunWorkerCompleted += (s, e) =>
{
    // Executes on UI thread upon completion.
    resultTextBox.Text = result;
};

bw.RunWorkerAsync();
于 2012-06-08T13:54:20.723 回答
0

这是代码示例 [你想要什么] - http://www.yoda.arachsys.com/csharp/threads/winforms.shtml

& 你可以在这里阅读所有的异步风格——

http://msdn.microsoft.com/en-us/library/2e08f6yc(v=vs.100).aspx

于 2012-06-08T14:06:19.870 回答