Wait()导致UI线程挂起 - 何时应该使用Wait()?

Nul*_*nce 2 .net c# task-parallel-library async-await signalr

我有以下代码连接到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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

StartListening();
Run Code Online (Sandbox Code Playgroud)

但是,Resharper提示我"考虑将'await'运算符应用于调用的结果"

所以我这样做了:

Log.Info("Connecting to SignalR hub...");
StartListening().Wait();
Log.Info("Connected!");
Run Code Online (Sandbox Code Playgroud)

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

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

Mar*_*ell 5

await不是Wait.目前还不清楚调用的代码是什么StartListening(),但有一个选项就是await它,如建议的那样:

await StartListening();
Run Code Online (Sandbox Code Playgroud)

但是,在其他一些情况下,最好什么都不做:

StartListening(); // drop the Task on the floor
Run Code Online (Sandbox Code Playgroud)

或者可能ContinueWith用于手动延续.由于该StartListening方法捕获了任何异常,因此忽略返回没有任何问题Task- 所以你已经拥有了.不过我建议打电话给我StartListeningAsync.

死锁的原因是,如果你使用Wait,你的UI线程阻塞等待异步方法完成,但该异步方法正在捕获sync-context,这意味着为了处理每个延续,它试图进入UI线程-这被封锁...... .

  • @ the8thbit远; "等等"是我要求你做某事,然后我就站在你身后,除非你完成它,否则什么都不做.如果我要求你做某事,那么"等待"就是这样,然后当你完成时,当我不在某事的中间时,来拍我肩膀.的种类.类比很糟糕; p这里的"同步上下文"是*"如何吸引我的注意力" - 但这有点拉伸了一些东西; p但是要说明:一个选择是告诉它*不要*捕捉同步-context - in*that*case,当你完成时,**你会去做我想做的任何事情 (2认同)