当您单击按钮时,我有一个winform,它调用任务等待功能,但是它冻结了,我不确定为什么。
private async Task GetsData()
{
var connectionString = "mongodb://localhost:27017";
var client = new MongoClient(connectionString);
IMongoDatabase db = client.GetDatabase("mydb");
var collection = db.GetCollection<BsonDocument>("mydata");
using (var cursor = await collection.Find(new
BsonDocument()).ToCursorAsync())
{
while (await cursor.MoveNextAsync())
{
foreach (var doc in cursor.Current)
{
MessageBox.Show(doc.ToString());
}
}
}
}
private void button1_Click(object sender, EventArgs e)
{
try
{
GetsData().Wait();
}
catch(Exception err)
{
MessageBox.Show(err.ToString());
}
}
我怎么能阻止它冻结?
答案 0 :(得分:0)
Task.Wait()
是一项阻止操作。它将阻止GUI线程等待GetsData()
返回的任务/承诺得到解决。同时,SynchronizationContext将针对GUI线程对WinForms应用中的异步调度进行调度。由于GUI线程被Wait()
阻塞,因此无法执行这些工作单元来解决任务,从而导致死锁。
使用异步等待时,最好在代码中一直使用。使用async-await进行任何线程阻塞时,很容易以死锁结束。首次引入async-await时,Stephen Cleary对此发表了很多精彩的文章。
要解决,有一些可能的路径,但是这种情况下最简单的方法可能是将事件处理程序转换为async void
方法和await
GetsData()
调用,而不是使用Wait()
。事件处理程序是async void
公认的理想选择。
private async void button1_Click(object sender, EventArgs e)