【发布时间】:2019-07-15 19:58:36
【问题描述】:
我在使用 UWP StreamSocket 时遇到了一个非常奇怪的异常,该代码在 99.9% 的情况下按预期运行并且与设备的通信正常,但是我每隔一段时间就会遇到以下异常。
异常消息:
操作失败,因为指定了无效的工作队列 ID 和标志组合。 (来自 HRESULT 的异常:0xC00D36FF)
问题的示例代码:
using (StreamSocket analyzerSocket = new StreamSocket())
{
HostName hostName = new HostName(host);
// Set NoDelay to false so that the Nagle algorithm is not disabled
analyzerSocket.Control.NoDelay = false;
try
{
// Connect to the server
await analyzerSocket.ConnectAsync(hostName, port.ToString()).AsTask(new CancellationTokenSource(_timeout).Token);
}
catch (Exception e)
{
var x = e;
}
}
堆栈跟踪:
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at Analyzer.<SendMessageAsync>d__120.MoveNext() in zzz.cs:line 779
我已经尝试了我的 GoogleFu,并且能够找到 MediaPlayer 或 Linux 内核的问题,但似乎与 StreamSockets 的这个问题无关。
虽然我可以捕获此错误并解决该问题,但我想知道发生了什么,以防它是更大问题的征兆。
提前致谢。
编辑 1
我认为这可能与http://referencesource.microsoft.com/#mscorlib/system/runtime/compilerservices/TaskAwaiter.cs,be57b6bc41e5c7e4有关,基于“//如果任务出错或取消则抛出异常”的代码注释。
但是,当我不使用“.AsTask(new CancellationTokenSource(timeout.Value).Token)”时,我仍然会遇到这种情况
编辑 2
当我有这个循环时,为了不断地向我们的设备发送消息,消息会一直被接收,直到发生这个异常。一旦发生异常并且我告诉它继续并重试,异常会在循环中一遍又一遍地再次发生,并且设备停止接收消息。
编辑 3
所以我尝试了以下方法,以使用 StreamSocket 对象的不同实例连接到不同的设备......它会产生相同的错误!
using (StreamSocket analyzerSocket = new StreamSocket())
{
HostName hostName = new HostName(host);
// Set NoDelay to false so that the Nagle algorithm is not disabled
analyzerSocket.Control.NoDelay = false;
try
{
// Connect to the server
await analyzerSocket.ConnectAsync(hostName, port.ToString()).AsTask(new CancellationTokenSource(_timeout).Token);
}
catch (Exception e)
{
using (StreamSocket analyzerSocket2 = new StreamSocket())
{
HostName hostName2 = new HostName("xxx.xxx.xxx.xxx");
// Set NoDelay to false so that the Nagle algorithm is not disabled
analyzerSocket.Control.NoDelay = false;
// Connect to the server
await analyzerSocket2.ConnectAsync(hostName2, port.ToString());
}
throw;
}
}
感觉像是某种跨线程类型的问题...我现在正抓着稻草,因为我无法捕获和绕过错误,因为一旦发生错误,我就无法再与设备对话,我必须退出应用程序让它再次工作。
是否有人有任何其他想法或确认它看起来像跨线程类型的问题?
提前致谢。
【问题讨论】:
-
SocketError.GetStatus 方法可用于将网络错误从套接字操作转换为SocketErrorStatus enumeration 值。您可以尝试获取错误状态并专门处理此异常。
-
@GraceFeng-MSFT 谢谢你的想法,但在我的情况下,SocketError.GetStatus 返回“未知”。我倾向于referencesource.microsoft.com/#mscorlib/system/runtime/… 是基于此评论的问题“// 如果任务出错或取消,则抛出异常。”...
-
那是 MF_E_INVALID_WORKQUEUE。仅由 Media Foundation 生成的错误代码。支持媒体播放的 Windows 组件。异常的堆栈跟踪很差,但它与网络错误有关的几率应该为零。
-
@HansPassant 是的,我也看到了,但是当我打开广泛的错误抛出时,基本上停止任何事情,它肯定会在 .ConnectAscync 方法上抛出异常。