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 超时的新线程调用它,一切正常。
我正在开发 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 超时的新线程调用它,一切正常。