从未尝试使用Windows窗体进行异步调用。我不能使用新的aynch/await
,因为我不拥有最近的Visual Studio / .NET。我需要的是"执行一个请求很长时间的操作(填充IList)"并且,当它完成后,在TextBox上写下该列表的结果。
在互联网上搜索我发现这个例子似乎有用,但TOO在我看来符合(也许有些事情快速而简单):
private void button1_Click(object sender, EventArgs e)
{
MyTaskAsync();
}
private void MyTaskWorker()
{
// here I populate the list. I emulate this with a sleep of 3 seconds
Thread.Sleep(3000);
}
private delegate void MyTaskWorkerDelegate();
public void MyTaskAsync()
{
MyTaskWorkerDelegate worker = new MyTaskWorkerDelegate(MyTaskWorker);
AsyncCallback completedCallback = new AsyncCallback(MyTaskCompletedCallback);
AsyncOperation async = AsyncOperationManager.CreateOperation(null);
worker.BeginInvoke(completedCallback, async);
}
private void MyTaskCompletedCallback(IAsyncResult ar)
{
MyTaskWorkerDelegate worker = (MyTaskWorkerDelegate)((AsyncResult)ar).AsyncDelegate;
AsyncOperation async = (AsyncOperation)ar.AsyncState;
worker.EndInvoke(ar);
AsyncCompletedEventArgs completedArgs = new AsyncCompletedEventArgs(null, false, null);
async.PostOperationCompleted(delegate(object e) { OnMyTaskCompleted((AsyncCompletedEventArgs)e); }, completedArgs);
}
public event AsyncCompletedEventHandler MyTaskCompleted;
protected virtual void OnMyTaskCompleted(AsyncCompletedEventArgs e)
{
if (MyTaskCompleted != null)
MyTaskCompleted(this, e);
// here I'll populate the textbox
textBox1.Text = "... content of the Iteration on the List...";
}
对于这种简单的操作,我真的需要像50行代码这样的东西吗?或者我可以删除一些东西?完成后我只需要一个简单的异步调用 - >回调。
没有锁,根本没有并发......
答案 0 :(得分:2)
您可以将CPL与C#4.0一起使用,如下所示:
private void button1_Click(object sender, EventArgs e)
{
Task.Factory.StartNew(() => DoWork())
.ContinueWith(t => UpdateUIWithResults(t.Result)
, CancellationToken.None
, TaskContinuationOptions.None
, TaskScheduler.FromCurrentSynchronizationContext());
}
这在线程池线程中启动DoWork
,允许它从UI线程中进行处理,然后在UI线程中运行UpdateUIWithResults
,并将结果传递给DoWork
。
答案 1 :(得分:0)
您可以使用Task.Factory.StartNew
将工作推送到线程池。 Task.ContinueWith
会给你一个“完成的回调”。
private void button1_Click(object sender, EventArgs e)
{
var ui = TaskScheduler.FromCurrentSynchronizationContext();
Task<List<T>> task = Task.Factory.StartNew(() => MyTaskWorker());
task.ContinueWith(t => OnMyTaskCompleted(t), ui);
}
private List<T> MyTaskWorker()
{
// here I populate the list. I emulate this with a sleep of 3 seconds
Thread.Sleep(3000);
return ...;
}
protected virtual void OnMyTaskCompleted(Task t)
{
// here I'll populate the textbox with t.Result
textBox1.Text = "... content of the Iteration on the List...";
}