WebSocket SendAsync期间处于压力下的未观察到的任务异常

时间:2017-10-03 21:38:17

标签: c# exception websocket task cancellation

我正在强调我正在编写的一项服务使用WebSocket取自AcceptWebSocketAsync。我用来通过WebSocket发送消息的代码是:

    static bool
    SendMessage(WebSocket webSocket, WebSocketMessage message, byte[] buffer, CancellationToken cancellationToken)
    {
        try {
            var endOfMessage = false;
            do {
                using(var timeout = new CancellationTokenSource(webSocketsTimeout))
                using(var lcts    = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeout.Token)) {
                    var count    = message.Content.Read(buffer, 0, buffer.Length);
                    endOfMessage = count < buffer.Length;
                    // ReSharper disable once MethodSupportsCancellation
                    webSocket
                        .SendAsync(new ArraySegment<byte>(buffer, 0, count), message.Type, endOfMessage, lcts.Token)
                        .Wait() // SendAsync should be canceled using the Token.
                    ;
                }
            } while(endOfMessage == false);

            return true;
        }
        catch(Exception e) {
            TraceConnectionError(e);
            return false;
        }
        finally {
            message.Dispose();
        }
    }

我的问题是在“压力”下(我每隔30秒打开和关闭6个连接,直到系统出现故障),我得到了:

  Unhandled Exception: System.AggregateException: A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread. ---> System.Net.HttpListenerException: An operation was attempted on a nonexistent network connection
     at System.Net.WebSockets.WebSocketHttpListenerDuplexStream.WriteAsyncFast(HttpListenerAsyncEventArgs eventArgs)
     at System.Net.WebSockets.WebSocketHttpListenerDuplexStream.<MultipleWriteAsyncCore>d__38.MoveNext()
  --- End of stack trace from previous location where exception was thrown ---
     at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
     at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
     at System.Net.WebSockets.WebSocketBase.<SendFrameAsync>d__48.MoveNext()
  --- End of stack trace from previous location where exception was thrown ---
     at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
     at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
     at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
     at System.Net.WebSockets.WebSocketBase.WebSocketOperation.<Process>d__19.MoveNext()
  --- End of stack trace from previous location where exception was thrown ---
     at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
     at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
     at System.Net.WebSockets.WebSocketBase.<SendAsyncCore>d__47.MoveNext()
     --- End of inner exception stack trace ---
     at System.Threading.Tasks.TaskExceptionHolder.Finalize()

我使用的Wait()不应该足以“观察”任务异常吗?

1 个答案:

答案 0 :(得分:1)

问题是.NET框架代码中的竞争条件。

我已经报告了错误here

作为一种解决方法,我会保留一份使用过的WebSockets列表,我会定期检查std::ifstream inFile(<path>); if (!inFile.is_open()) { exit(1); // Handle error } std::string line; while(std::getline(inFile, line)) { std::cout << line << std::endl; } ,然后调用此代码:

State != Open