C# Task.Delay()挂起分钟

C# Task.Delay()挂起分钟,c#,.net,sqlite,xamarin,deadlock,C#,.net,Sqlite,Xamarin,Deadlock,我正在开发Xamarin.iOS应用程序,我正在调用wait Task.whenay(tcs.Task,Task.Delay(msTimeout))msTimeout设置为8000。问题是,有时它不能在给定的8000毫秒延迟内完成,并挂起几分钟(请参阅日志) 我已经读到使用task.Wait()可能会导致这种行为,但我在解决方案中的任何地方都没有使用它,我还将其从Parse SDK开源库中删除(但我猜它仍然可以在其他一些非开源库中使用..) 我还读到使用task.Result可能会导致这种情况,

我正在开发Xamarin.iOS应用程序,我正在调用
wait Task.whenay(tcs.Task,Task.Delay(msTimeout))msTimeout设置为8000。问题是,有时它不能在给定的8000毫秒延迟内完成,并挂起几分钟(请参阅日志)

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

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

我也在使用SQLite,最近SQLite也出现了一些挂起,所以它可能与这个问题有关。我使用的是SQLiteAsyncConnection单例实例和SQLiteConnection单例实例。我认为使用这两种方法可能都是不好的做法,所以我只是设法只使用SQLiteAsyncConnection单例实例,但没有任何帮助

我还尝试了VisualStudio中的“全部中断”选项,以查看下一行代码,但它总是告诉我“框架不在模块中”

你能分享一下你的想法吗?还有什么会导致我的应用程序出现这些奇怪的挂起,或者我该如何解决

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

代码:

返回等待任务。运行(异步()=> { 尝试 { Console.WriteLine(“可远程访问1”); var tcs=new TaskCompletionSource(); var hostEntry=新的DnsEndPoint(主机、端口); 控制台写入线(“远程可达2”); 使用(var套接字=新套接字(AddressFamily.InterNetwork、SocketType.Stream、ProtocolType.Tcp)) { Console.WriteLine(“可远程访问的3”); var socketEventArg=new SocketAsyncEventArgs{RemoteEndPoint=hostEntry}; SocketEventTarget.Completed+=(s,e)=> { WriteLine(“REMOTEREACHABLE COMPLETED:”+(e.SocketError==SocketError.Success)); tcs.TrySetResult(e.SocketError==SocketError.Success); }; 控制台写线(“远程可达4”); socket.ConnectAsync(socketEventArg); Console.WriteLine(“可远程访问的5”); wait Task.whenay(tcs.Task,Task.Delay(msTimeout)); 如果(!tcs.Task.IsCompleted) Console.WriteLine(“远程访问超时”); var result=tcs.Task.IsCompleted&等待tcs.Task; Console.WriteLine(“远程可达6:+结果”); 返回结果; } } 捕获(例外情况除外) { Debug.WriteLine(“无法访问:“+host+”错误:“+ex”); 返回false; } });
日志:

2016-03-16 19:32:42.254应用程序[3309:6203]可远程访问1
2016-03-16 19:32:42.259应用程序[3309:6203]远程可访问2
2016-03-16 19:32:42.306应用程序[3309:6203]可远程访问3
2016-03-16 19:32:42.319应用程序[3309:6203]远程可访问4
线程已启动:#8
2016-03-16 19:32:43.039应用程序[3309:6203]远程可访问5
线程已启动:#9
螺纹加工:#8
线程已启动:#10
螺纹加工:#10
2016-03-16 19:34:05.471应用程序[3309:6203]远程可访问超时
2016-03-16 19:34:05.478应用程序[3309:6203]远程可访问6:错误

好的,我终于明白了。最有可能的原因是
网络可达性。当网络数据包丢失率为100%或在没有互联网的wifi上时,TryGetFlags
会阻止Xamarin.iOS上的应用程序。我使用的是Xamarin连接插件,它在内部调用
TryGetFlags
。我描述了这个问题。现在我用返回超时从新线程调用它,一切正常。

如果线程池耗尽,可能会发生这种情况。您是否能够在最小的应用程序中复制?使用desktop.NET如何?@StephenCleary我没有尝试使用minimal或desktop应用程序,这将非常耗时,因为它只在同一时间发生,可能无助于找到原因和解决方案(“它不会在desktop.NET中发生”如何帮助我?)。然而,我在应用程序启动几秒钟后调用了这段代码,所以我想它不应该被耗尽。如果线程池已耗尽,我可以做些什么来防止这种情况发生?如果您可以用最少的示例可靠地重新生成线程池,通常很容易发现问题。这是解决任何问题的第一步,无论是你自己的问题还是别人的问题。自己不做只是意味着其他人必须做。重新。Desktop.NET:Desktop使用的BCL与Xamarin不同(目前),大多数回答者都有可用的桌面,但Xamarin没有,所以如果你能在桌面上找到它,你可能的回答者数量会显著增加。此外,在Xamarin中发现了(许多)与任务/线程相关的bug,但这些bug并没有出现在桌面上。我完全同意@StephenCleary!这无疑有助于获得足够的信息,使我们能够重现问题并在标准桌面/VS环境中进行分析。顺致敬意,
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