Task.Delay() 挂起几分钟

Task.Delay() hangs for minutes

我正在开发 Xamarin.iOS 应用程序,我在调用 await Task.WhenAny(tcs.Task, Task.Delay(msTimeout)); 时将 msTimeout 设置为 8000。问题是,有时 它没有在给定 8000 毫秒延迟并挂起几分钟(查看日志)。

我读到过使用 task.Wait() 会导致这种行为,但我没有在我的解决方案中的任何地方使用它,我也从 Parse SDK 开源库中删除了它(但我想它仍然可以在其他一些非开源库中使用..)。

我还读到使用 task.Result 会导致这种情况,但我检查了我的解决方案和 Parse 库,它只用于某些 .ContinueWith(t => return t.Result).OnSuccess 我认为是的情况好的(如果我错了请纠正我)。

我也在使用 SQLite,最近 SQLite 也出现了一些挂起问题,因此可能与此问题有关。我正在使用 SQLiteAsyncConnection 单例实例和 SQLiteConnection 单例实例。我认为同时使用两者可能是不好的做法,所以我只设法使用 SQLiteAsyncConnection 单例实例,但它没有帮助。

我也尝试了 Visual Studio 中的 "Break All" 选项来查看下一行代码,但它总是告诉我 "frame not in module".

能否请您分享您的想法,还有什么可能导致我的应用程序出现这些奇怪的挂起,或者我该如何解决?

编辑: 我刚刚发现挂起 Task.Delay 可能不是挂起状态的根本原因,而是因为应用程序在几秒钟前进入挂起状态而挂起。它确实也影响了 SQLite。我会继续调查..

代码:

return await Task.Run(async () =>
   {
      try
      {
           Console.WriteLine("REMOTEREACHABLE 1");
           var tcs = new TaskCompletionSource<bool>();
           var hostEntry = new DnsEndPoint(host, port);
           Console.WriteLine("REMOTEREACHABLE 2");

           using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
           {
               Console.WriteLine("REMOTEREACHABLE 3");
               var socketEventArg = new SocketAsyncEventArgs { RemoteEndPoint = hostEntry };
               socketEventArg.Completed += (s, e) =>
               {
                   Console.WriteLine("REMOTEREACHABLE COMPLETED:" + (e.SocketError == SocketError.Success));
                   tcs.TrySetResult(e.SocketError == SocketError.Success);
               };

               Console.WriteLine("REMOTEREACHABLE 4");
               socket.ConnectAsync(socketEventArg);
               Console.WriteLine("REMOTEREACHABLE 5");
               await Task.WhenAny(tcs.Task, Task.Delay(msTimeout));
               if (!tcs.Task.IsCompleted)
                    Console.WriteLine("REMOTEREACHABLE TIMED OUT");
               var result = tcs.Task.IsCompleted && await tcs.Task;
               Console.WriteLine("REMOTEREACHABLE 6:" + result);
               return result;
           }
      }
      catch (Exception ex)
      {
            Debug.WriteLine("Unable to reach: " + host + " Error: " + ex);
            return false;
      }
});

日志:

2016-03-16 19:32:42.254 AppiOS[3309:6203] REMOTEREACHABLE 1
2016-03-16 19:32:42.259 AppiOS[3309:6203] REMOTEREACHABLE 2
2016-03-16 19:32:42.306 AppiOS[3309:6203] REMOTEREACHABLE 3
2016-03-16 19:32:42.319 AppiOS[3309:6203] REMOTEREACHABLE 4
Thread started:  #8
2016-03-16 19:32:43.039 AppiOS[3309:6203] REMOTEREACHABLE 5
Thread started: <Thread Pool> #9
Thread finished:  #8
Thread started:  #10
Thread finished:  #10
2016-03-16 19:34:05.471 AppiOS[3309:6203] REMOTEREACHABLE TIMED OUT
2016-03-16 19:34:05.478 AppiOS[3309:6203] REMOTEREACHABLE 6:False

好吧,我终于明白了。这很可能是由于 NetworkReachability.TryGetFlags 在网络丢包 100% 时或在没有互联网的 wifi 上时在 Xamarin.iOS 上阻止应用程序造成的。我正在使用调用内部 TryGetFlags 的 Xamarin Connectivity 插件。我描述了这个问题 here。现在我从 return 超时的新线程调用它,一切正常。