C#Task.Wait Freezin

时间:2019-05-24 03:08:06

标签: c#

当您单击按钮时,我有一个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());
            }
        }

我怎么能阻止它冻结?

1 个答案:

答案 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)