偶尔会通过WebApi以流传输模式将压缩内容写入客户端的异常

问题描述 投票:0回答:1

我们有一个WEPAPI服务,该服务使用消息处理程序以压缩形式将数据写入客户端。由于我们偶尔会收到非常大的消息,因此可以使用

配置系统
HttpSelfHostConfiguration.TransferMode = TransferMode.Streamed;

压缩逻辑是:

public class CompressedHttpContent : CompressionHttpContent
{
    public CompressedHttpContent(HttpContent content, ICompressor compressor)
        : base(content, compressor)
    {
    }

    protected async override Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext context)
    {
        try
        {
            if (this.OriginalContent != null)
                using (OriginalContent)
                {
                    using (var contentStream = await OriginalContent.ReadAsStreamAsync())
                    {
                        var compressedStream = Compressor.CreateCompressionStream(stream);
                        await contentStream.CopyToAsync(compressedStream);
                        compressedStream.Close();
                        compressedStream.Dispose();
                    }
                }
        }
        catch (Exception e)
        {
            ...
            throw;
        }
    }
}

[偶尔我们会收到类似的异常:

System.InvalidOperationException: The AsyncEventArgs implementation 'System.ServiceModel.Channels.BufferedOutputAsyncStream+WriteAsyncState' tried to set the state to Pending multiple times without completing a pending operation. This could be caused by an incorrect application AsyncEventArgs implementation or other extensibility code that invokes Set() multiple times.
Server stack trace:
at System.Runtime.AsyncEventArgs.set_State(OperationState value)
at System.Runtime.AsyncEventArgs.SetAsyncState(AsyncEventArgsCallback callback, Object state)
at System.Runtime.AsyncEventArgs`1.Set(AsyncEventArgsCallback callback, TArgument arguments, Object state)
at System.ServiceModel.Channels.BufferedOutputAsyncStream.BeginWrite(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
at System.IO.Compression.DeflateStream.WriteDeflaterOutput(Boolean isAsync)
at System.IO.Compression.DeflateStream.InternalWrite(Byte[] array, Int32 offset, Int32 count, Boolean isAsync)
at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs)
at System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg, IMessageSink replySink)
Exception rethrown at [0]:
at System.IO.Compression.DeflateStream.EndWrite(IAsyncResult asyncResult)
at System.IO.Compression.GZipStream.EndWrite(IAsyncResult asyncResult)
at System.IO.Stream.<>c.<BeginEndWriteAsync>b__53_1(Stream stream, IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory`1.FromAsyncTrimPromise`1.Complete(TInstance thisRef, Func`3 endMethod, IAsyncResult asyncResult, Boolean requiresSynchronization)
--- 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.IO.Stream.<CopyToAsyncInternal>d__27.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 CompressedHttpContent.<SerializeToStreamAsync>d__2.MoveNext()

不幸的是,当我搜索此错误时,没有得到任何点击。

当我们使用缓冲传输模式时,我们没有得到这个。我们可能会更改为StreamedRequest模式,因为只有传入的请求可能非常大。

有人见过这个或有什么想法吗?

谢谢。

c# asp.net-web-api invalidoperationexception
1个回答
0
投票
当前BufferedOutputAsyncStream仅用于包装同时满足两个要求的System.Net.HttpResponseStream。”(https://referencesource.microsoft.com/#System.ServiceModel/System/ServiceModel/Channels/BufferedOutputAsyncStream.cs

GZipStream似乎没有满足此要求,可以通过一些简单的代码进行测试(通常会引发异常)。

byte[] ba = File.ReadAllBytes(@"largerfile"); GZipStream gzs = new GZipStream(new MemoryStream(), CompressionLevel.Optimal); gzs.WriteAsync(ba,0, 200000); gzs.WriteAsync(ba, 0, 200000);

[我怀疑ASP.NET WebAPI可能以不受支持的方式调用GZipStream-尽管我尚不确信这​​实际上是正在发生的事情。

© www.soinside.com 2019 - 2024. All rights reserved.