【发布时间】:2014-12-20 05:10:36
【问题描述】:
我遇到了一个非常奇怪的行为。经过大量挖掘后,我找到了一个场景,该场景显示(显然)直接从 WFP 应用程序使用任务 await 不能按预期工作。但是,创建一个任务并在其中执行 await 可以正常工作。
我使用以下步骤进行说明(使用 VS 2013)。在一个新的 WPF 应用程序中使用这个 main.xaml.cs:
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
static async Task<bool> Test_int()
{
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
Thread t = new Thread(() =>
{
Thread.Sleep(1000);
tcs.SetResult(true);
//Console.WriteLine("TCS set");
});
t.Start();
//int i = tcs.Task.Result; //<-- this always works, but doesn't take advantage of await semantics
var ret = await tcs.Task;
return ret;
}
static void Test()
{
var tt = Test_int();
//(1)
tt.Wait();
//Console.WriteLine("Test done");
}
public MainWindow()
{
InitializeComponent();
//option 1 -- works
Task t = new Task(Test);
t.Start();
t.Wait();
//option 2 -- hangs indefinitely
Test();
}
}
}
我看到的行为是运行方法 Test() 直接导致应用程序挂起(在标有 (1) 的 await 行中),而在任务中运行它会正确运行并完成。
我通过在任务上下文中运行解决了我最初的问题,但我想了解问题的原因。顺便说一句,在控制台应用程序中运行时,相同的 Test() 方法确实可以直接工作。
直接从 WPF 应用程序运行时,为什么不等待工作(以相同的方式)?
【问题讨论】:
-
您应该避免在 WPF 中调用
Task.Wait()。正如您所做的那样,很容易引入死锁。 -
@Cory Nelson 这是问题的一个例证。等待只是表明(1)等待永远不会返回。
-
请记住,死锁有两个或多个端点。
Wait()只是一端。另一个是await。
标签: c# wpf async-await