C# 如果启用了异步任务,则异步任务的UI命令*previous*不起作用
我不能像我想的那样掌握异步的东西,因为这已经让我挠头好几个小时了 我想要实现的是: 将UI切换到获取数据。。。 使用异步调用获取数据 基于异步调用显示最终结果 在我的视图中,我有以下来自WPF按钮的回调C# 如果启用了异步任务,则异步任务的UI命令*previous*不起作用,c#,wpf,asynchronous,async-await,wpf-controls,C#,Wpf,Asynchronous,Async Await,Wpf Controls,我不能像我想的那样掌握异步的东西,因为这已经让我挠头好几个小时了 我想要实现的是: 将UI切换到获取数据。。。 使用异步调用获取数据 基于异步调用显示最终结果 在我的视图中,我有以下来自WPF按钮的回调 private void Button_Click(object sender, RoutedEventArgs e) { GeneratorButton.IsEnabled = false; ResultMsg.Visibility = Visi
private void Button_Click(object sender, RoutedEventArgs e)
{
GeneratorButton.IsEnabled = false;
ResultMsg.Visibility = Visibility.Visible; //default text of "Fetching data..."
string tickersString = Tickers.Text;
if (!string.IsNullOrEmpty(tickersString))
{
tickersString = tickersString.ToUpper();
string[] tickers = tickersString.Split(',', ' ');
var stockGeneratorTask = Task.Factory.StartNew<bool>(() => GetStockDataAndGenerateCSV(tickers).Result);
var allTasks = new Task[] { stockGeneratorTask };
var tasksHandler = Task.Factory.ContinueWhenAll(allTasks, completedTasks =>
{
return stockGeneratorTask.Result;
});
if (tasksHandler.Result)
{
ResultMsg.Foreground = Brushes.Green;
ResultMsg.Text = "Your report was successfully generated.";
}
else
{
ResultMsg.Text = "There was an error while generating your report. Please try again later.";
ResultMsg.Foreground = Brushes.Red;
}
}
GeneratorButton.IsEnabled = true;
}
我的期望是,一旦用户点击按钮,他们就会看到获取数据的默认文本。。。由于可见性属性开关。据我所知,正在发生的事情是,程序直接进入异步任务,当它返回时,会显示成功或错误消息,但它会跳过获取数据。。。总之,除非我注释掉StockGeneratorTaskDown声明中的代码,否则不会发生异步调用
现在,如果这个可见性切换是在异步任务被触发之前发生的,那么我不应该在它实际进行异步调用之前看到这个更改吗?为什么我只在它返回后才看到它?事件处理程序是允许异步void的一个例外。考虑始终将事件处理程序异步化,不混合阻塞调用,例如,导致死锁的结果。假设GetStockDataAndGenerateCSV返回任务,那么应该等待它
private async void Button_Click(object sender, RoutedEventArgs e) {
GeneratorButton.IsEnabled = false;
ResultMsg.Visibility = Visibility.Visible; //default text of "Fetching data..."
var tickersString = Tickers.Text;
if (!string.IsNullOrEmpty(tickersString)) {
tickersString = tickersString.ToUpper();
string[] tickers = tickersString.Split(',', ' ');
if (await GetStockDataAndGenerateCSV(tickers)) {
ResultMsg.Foreground = Brushes.Green;
ResultMsg.Text = "Your report was successfully generated.";
} else {
ResultMsg.Foreground = Brushes.Red;
ResultMsg.Text = "There was an error while generating your report. Please try again later.";
}
}
GeneratorButton.IsEnabled = true;
}
参考资料除非我遗漏了什么。。。您只需要将方法def更改为private async void按钮,单击,除去tickers声明和if语句之间的所有内容,并将if更改为:ifawait GetStockDataAndGenerateCSVtickers。。。。您现在访问任务的Result属性而不等待它的方式是阻塞,即不异步。您的代码都是同步的。不要使用Task.Factory.StartNew,除非您需要。