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

时间:2009-10-16 18:41:10

标签: winforms invoke asynchronous

我找不到这个问题的解决方案,这里是简化的例子: 在Windows窗体上,我有2个文本框(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));
            }
        });
    }

单击一个按钮时,它仅更新其相关文本框。 单击两个按钮时,每个按钮都会更新两个文本框。

我认为应该有一些简单的东西,但我找不到:(

1 个答案:

答案 0 :(得分:0)

哦,问题解决了!这是因为我多次订阅同一个事件:

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();
            }));
        });
    }