我找不到这个问题的解决方案,这里是简化的例子: 在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));
}
});
}
单击一个按钮时,它仅更新其相关文本框。 单击两个按钮时,每个按钮都会更新两个文本框。
我认为应该有一些简单的东西,但我找不到:(
答案 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();
}));
});
}