【发布时间】:2020-02-19 01:09:45
【问题描述】:
我有以下代码:
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()与上一次调用的结果
因此我想使用异步模型来编写这个。
我该怎么办?
【问题讨论】:
-
define "能够链接多个调用"
-
@MichaelRandall:
Task.Run会发生这种情况,但问题在于使事件处理程序异步并且不使用Task.Run。这种变化的推动力可能是因为必须使用Dispatcher.Invoke来返回 UI 线程。 -
@madreflection
Dispatcher.Invoke()根本不需要使用。如果您var attempt = await TaskRun(() => someLibrary.doSomethingWith(input));,您可以使用结果来设置 UI。这不需要时间。好吧,只是重复我在之前的评论中写的内容。 -
@madreflection 这里没有什么可以从异步中受益。嗯,显然有。 能够链接多个调用部分是最终需要讨论的部分。如果您要更新相同的控件,您会链接什么?或者,它还有其他用途吗?也许这个程序必须随意重复?那么,MessageBox...?
-
我的意思是,除了 OP 希望删除的
Task.Run之外,该代码中没有任何内容是可等待的。
标签: c# async-await