c# - Wait() 导致 UI 线程挂起 - 什么时候应该使用 Wait()?

标签 c# .net task-parallel-library signalr async-await

我有以下连接到 SignalR Hub 的代码

    private static async Task StartListening()
    {
        try
        {


            var hubConnection = new HubConnection("http://localhost:8080/");                
            IHubProxy hubProxy = hubConnection.CreateHubProxy("Broadcaster");
            hubProxy.On<EventData>("notifyCardAccessEvent", eventData =>
            {
                Log.Info(string.Format("Incoming data: {0} {1}", eventData.Id, eventData.DateTime));
            });
            ServicePointManager.DefaultConnectionLimit = 10;
            await hubConnection.Start();
            Log.Info("Connected");
        }
        catch (Exception ex)
        {
            Log.Error(ex);
        }
    }

在我的 Form_Load 方法中,我有这个

StartListening();

但是,Resharper 提示我“考虑将‘await’运算符应用于调用结果”

所以我这样做了:

Log.Info("Connecting to SignalR hub...");
StartListening().Wait();
Log.Info("Connected!");

但是,这会导致我的 UI 线程挂起并且 Connected! 永远不会打印到日志文件中。

所以我的问题是,什么时候应该使用Wait()?哪些情况和场景应该使用Wait(),什么时候不应该使用Wait()

最佳答案

await 不是等待。目前尚不清楚调用 StartListening() 的代码是什么,但一种选择是 await 它,如建议的那样:

await StartListening();

然而,在其他一些情况下,什么都不做可能会更好:

StartListening(); // drop the Task on the floor

或者可能使用 ContinueWith 进行手动延续。由于 StartListening 方法捕获任何异常,因此忽略返回的 Task 没有任何问题 - 所以您已经拥有了。不过,我建议将其称为 StartListeningAsync

死锁的原因是,如果您使用Wait,您的 UI 线程会阻塞等待异步方法完成,但该异步方法正在捕获同步上下文,这意味着为了处理它试图进入 UI 线程的每个延续——它被阻塞了……在它上面

关于c# - Wait() 导致 UI 线程挂起 - 什么时候应该使用 Wait()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22706880/

相关文章:

C# System.Diagnostics.Process : how to exit a process if it takes more than, 说,10 秒?

c# - InvalidOperationException 与 MediaLibrary 图片

c# - 2013 年末使用 Oracle 数据库的 .NET 应用程序有哪些数据访问选项?

c# - Task.Factory.StartNew 与 Task.Factory.FromAsync

c# - 通用列表 : The type arguments for method cannot be inferred from the usage in lambdas

c# - 使用属性将枚举序列化为 JSON.NET 中的字符串

c# - 动态添加组合框中的项目和用户添加的项目应该是永久的而不使用数据库,可能吗?

c# - 如何使用 ResourceExposureAttribute 和 ResourceConsumptionAttribute?

c# - 传入字典的模型项的类型为 'System.Threading.Tasks.Task` 1[System.Collections.Generic.IEnumerable`

c# - 在任务完成之前关闭 WPF 窗口