Winforms 异步调用更改两个控件后调用

Winforms 异步调用更改两个控件后调用,winforms,invoke,asynchronous,Winforms,Invoke,Asynchronous,我无法找到此问题的解决方案,以下是简化的示例: 在windows窗体上,我有两个文本框(invokeText1、invokeText2)和两个按钮(invokeButton1、invokeButton2)。 有两种按钮点击: private void invokeButton1_Click(object sender, EventArgs e) { Form1.GetVersionCompleted += (object sender1, AsyncCompletedEv

我无法找到此问题的解决方案,以下是简化的示例: 在windows窗体上,我有两个文本框(invokeText1、invokeText2)和两个按钮(invokeButton1、invokeButton2)。 有两种按钮点击:

private void invokeButton1_Click(object sender, EventArgs e)
    {
        Form1.GetVersionCompleted += (object sender1, AsyncCompletedEventArgs e1) =>
        {
            this.Invoke((MethodInvoker)(() =>
            {
                invokeText1.Text = DateTime.Now.ToString();
            }));
        };
        Form1.GetVersionAsync();
    }

    private void invokeButton2_Click(object sender, EventArgs e)
    {
        Form1.GetVersionCompleted += (object sender1, AsyncCompletedEventArgs e1) =>
        {
            this.Invoke((MethodInvoker)(() =>
            {
                invokeText2.Text = DateTime.Now.ToString();
            }));

        };
        Form1.GetVersionAsync();
    }
对异步方法的两个调用:

public static event EventHandler<AsyncCompletedEventArgs> GetVersionCompleted;

    public static void GetVersionAsync()
    {
        ThreadPool.QueueUserWorkItem(o =>
        {
            try
            {
                string result = DateTime.Now.ToString();

                GetVersionCompleted(
                    null,
                    new AsyncCompletedEventArgs(
                    null,
                    false,
                    result));
            }
            catch (Exception ex)
            {
                GetVersionCompleted(
                    null,
                    new AsyncCompletedEventArgs(
                    ex,
                    false,
                    null));
            }
        });
    }
公共静态事件事件处理程序GetVersionCompleted;
公共静态void GetVersionAsync()
{
ThreadPool.QueueUserWorkItem(o=>
{
尝试
{
字符串结果=DateTime.Now.ToString();
GetVersionCompleted(
无效的
新的AsyncCompletedEventArgs(
无效的
错误的
结果);
}
捕获(例外情况除外)
{
GetVersionCompleted(
无效的
新的AsyncCompletedEventArgs(
前任,
错误的
空);
}
});
}
单击单个按钮时,它仅更新其相关文本框。 单击两个按钮时,每个按钮都会更新两个文本框


我认为应该有一些简单的事情,但我找不到什么:(

哦,问题解决了!发生这种情况是因为我订阅了同一个事件好几次:

Form1.GetVersionCompleted += 
正确的实施方式如下:

public delegate void OnCompleted<T>(T result, Exception ex);

    public static void GetVersionAsync(OnCompleted<string> completed)
    {
        ThreadPool.QueueUserWorkItem(o =>
        {
            try
            {
                string result = DateTime.Now.ToString();
                if (completed != null)
                {
                    completed(result, null);
                }
            }
            catch (Exception ex)
            {
                if (completed != null)
                {
                    completed(null, ex);
                }
            }
        });
    }

private void invokeButton1_Click(object sender, EventArgs e)
    {
        Form1.GetVersionAsync((string result, Exception ex) =>
            {
                this.Invoke((MethodInvoker)(() =>
                {
                    invokeText1.Text = DateTime.Now.ToString();
                }));
            });
    }

    private void invokeButton2_Click(object sender, EventArgs e)
    {
        Form1.GetVersionAsync((string result, Exception ex) =>
        {
            this.Invoke((MethodInvoker)(() =>
            {
                invokeText2.Text = DateTime.Now.ToString();
            }));
        });
    }
public delegate void未完成(T结果,异常示例);
公共静态void GetVersionAsync(未完成已完成)
{
ThreadPool.QueueUserWorkItem(o=>
{
尝试
{
字符串结果=DateTime.Now.ToString();
如果(已完成!=null)
{
已完成(结果,空);
}
}
捕获(例外情况除外)
{
如果(已完成!=null)
{
已完成(空,ex);
}
}
});
}
私有void invokeButton1_单击(对象发送方,事件参数e)
{
Form1.GetVersionAsync((字符串结果,异常值)=>
{
this.Invoke((MethodInvoker)(()=>
{
invokeText1.Text=DateTime.Now.ToString();
}));
});
}
私有void invokeButton2_单击(对象发送方,事件参数e)
{
Form1.GetVersionAsync((字符串结果,异常值)=>
{
this.Invoke((MethodInvoker)(()=>
{
invokeText2.Text=DateTime.Now.ToString();
}));
});
}