我有以下代码片段:
现在,我想要:
我该怎么做?
private void btnAction_Click(object sender, RoutedEventArgs e)
{
/** Clear the results field */
txtResult.Text = "";
/** Disable the button and show waiting status */
btnAction.IsEnabled = false;
lblStatus.Text = "Wait...";
/** Get input from the query field */
string input = query.Text;
/** Run a new task */
Task.Run(() => {
// calling a method that takes a long time (>3s) to finish and return
var attempt = someLibrary.doSomethingWith(input);
// return the result to the GUI thred
this.Dispatcher.Invoke(() =>
{
if (attempt.ContainsKey("success"))
{
if (attempt["success"] == true)
{
txtResult.Text = "Success! The door is: " + (attempt["is_open"] ? "open" : "closed");
lblStatus.Text = "";
}
else
{
lblStatus.Text = "Error! The service says: " + attempt["errorMessage"];
}
}
else
{
MessageBox.Show("There was a problem getting results from web service.");
lblStatus.Text = "";
}
/** Re-enable the button */
btnAction.IsEnabled = true;
});
});
}
现在,我想要:
- 使用回调来编写相同的代码,而不是使用
Dispatcher.Invoke()
。 - 能够取消调用
doSomething()
的正在运行的任务 - 能够链接多个调用,即等待
doSomething()
完成后,使用前一个调用的结果来执行doAnotherThing()
我该怎么做?
Task.Run
发生的情况,但问题是如何使事件处理程序异步并且不使用Task.Run
。进行更改的动机可能是因为必须使用Dispatcher.Invoke
返回到UI线程。 - madreflectionDispatcher.Invoke()
完全不需要使用。如果你使用var attempt = await Task.Run(() => someLibrary.doSomethingWith(input));
,你可以使用结果来设置UI。这不会花费时间。就是在重复我之前评论中写的内容。 - JimiTask.Run
之外,那段代码中没有任何可等待的内容。 - madreflection