自托管的 o​​win webapi 发生奇怪的崩溃

Strange crash with an self hosted owin webapi

我有一个控制台应用程序,它自己托管一个将 pdf 转换为 pdfa 的 owin webapi 和另一个调用 webapi 的控制台应用程序。

问题有点奇怪。我可以用一个大小为 33KB 的文件连续调用 webapi 两次,但是如果我用一个 2.6mb 的文件调用它两次,从服务器的角度来看,它两次都是 returns 转换后的文件数据,但是第二次在服务器硬退出之前有一个短暂的延迟而不报告错误并且客户端报告以下嵌套异常。

1. "HttpRequestException: Error while copying content to a stream."
2. "Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host"
3. "An existing connection was forcibly closed by the remote host" 

现在服务器端代码

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        // Configure Web API for self-host. 
        HttpConfiguration config = new HttpConfiguration();
        config.MapHttpAttributeRoutes();
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        app.UseCors(CorsOptions.AllowAll);
        app.UseWebApi(config);

        JsonConvert.DefaultSettings = () => new JsonSerializerSettings
        {
            NullValueHandling = NullValueHandling.Ignore,
            Formatting = Formatting.None,
        };
    }
}

自托管服务器启动如下

WebApp.Start<Startup>(url);

控制器

public class ConvertPdfByteArrayToPdfaController : ApiController
{
    public ConvertPdfByteArrayToPdfaResponse Post([FromBody]ConvertPdfByteArrayToPdfaRequest request)
    {
        try
        {                    
            //lots of work here

            jsonLight = result.GetJsonLight();
            return result;
        }
        catch (Exception ex)
        {
            throw logger.LogExceptionForReThrow("There was a problem trying to convert the PDF to PDFa", ex);
        }
        finally
        {    
            logger.End("Returned", $"Returned: {jsonLight}");
        }
    }
}

这很好地完成了 return 并且记录器两次都成功了。

现在客户端

private HttpClient GetWebApiPdfClient(string serverHostName, int portNumber)
{
    var client = new HttpClient();
    client.BaseAddress = new Uri($"http://{serverHostName}:{portNumber}/");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json"));
    client.Timeout = TimeSpan.FromHours(2);
    client.MaxResponseContentBufferSize = 1000000000;
    return client;
}


public ConvertPdfByteArrayToPdfaResponse ConvertPdfByteArrayToPdfa(byte[] byteArray, bool certify)
{
    var request = new ConvertPdfByteArrayToPdfaRequest { PdfByteArray = byteArray, Certify = certify };
    return PostObject<ConvertPdfByteArrayToPdfaResponse>("api/convertPdfByteArrayToPdfa", request);
}

private T PostObject<T>(string endpoint, object data)
{
    using (var client = GetWebApiPdfClient())
    {
        var json = JsonConvert.SerializeObject(data);
        var content = new StringContent(json, Encoding.UTF8, "application/json");

        var response = client.PostAsync(endpoint, content).Result;  //Fails the second time here on a 2.6mb file but works fine for first file 2.6mb file
        var responseText = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();

        if (response.StatusCode != HttpStatusCode.OK)
            throw new Exception($"Expected returnCode:{HttpStatusCode.OK} but received {response.StatusCode}");
        if (response.Content.Headers.ContentLength > 0)
            return JsonConvert.DeserializeObject<T>(responseText);

        throw new Exception($"response content length was 0");
    }
}

调用代码

            var webApiPdfClient = new WebApiPdfClient();
            var response = webApiPdfClient.ConvertPdfByteArrayToPdfa(pdfOriginalFile.ReadAllBytes(), false);
            file1.WriteAllBytes(response.PdfaByteArray);
            var response2 = webApiPdfClient.ConvertPdfByteArrayToPdfa(pdfOriginalFile.ReadAllBytes(), false);
            file2.WriteAllBytes(response2.PdfaByteArray);

有两个 windows 服务器在硬崩溃时创建的事件日志 第一个错误事件日志条目

Faulting application name: xxxxxxxxService.exe, version: 1.0.0.0, time stamp: 0x94123e39
Faulting module name: ucrtbase.dll, version: 10.0.17134.677, time stamp: 0x9f346d3f
Exception code: 0xc0000409
Fault offset: 0x000000000006e14e
Faulting process ID: 0x4f7c
Faulting application start time: 0x01d537b0b4116e7c
Faulting application path: C:\xxxxxxxxService.exe
Faulting module path: C:\WINDOWS\System32\ucrtbase.dll
Report ID: a32399dd-a1d3-4493-9f6c-ef6cb45453e4
Faulting package full name: 
Faulting package-relative application ID: 

第二信息事件日志条目

Fault bucket 1930686170833522916, type 5
Event Name: BEX64
Response: Not available
Cab Id: 0

Problem signature:
P1: xxxxxxxxService.exe
P2: 1.0.0.0
P3: 94123e39
P4: ucrtbase.dll
P5: 10.0.17134.677
P6: 9f346d3f
P7: 000000000006e14e
P8: c0000409
P9: 0000000000000007
P10: 

Attached files:
\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WER1B21.tmp.mdmp
\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WER1D93.tmp.WERInternalMetadata.xml
\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WER1DA4.tmp.xml
\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WER1DB2.tmp.csv
\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WER1DD2.tmp.txt

These files may be available here:
C:\ProgramData\Microsoft\Windows\WER\ReportArchive\AppCrash_xxxxxxxx_c7be53f830b5ebee58beaeda68b8ea707ef39a54_6dd26e0f_1fb623ad

Analysis symbol: 
Rechecking for solution: 0
Report Id: a32399dd-a1d3-4493-9f6c-ef6cb45453e4
Report Status: 268435456
Hashed bucket: fd129a9a61ef2bd3facb2cd7d94a90e4
Cab Guid: 0

我只是不确定硬崩溃的原因是什么。

问题是由第三方库引起的,我没有按我应该做的处理。该库的试用版不会导致问题,但许可版本会导致问题。半间歇性和严重碰撞使定位变得更加困难。但是当我缩小范围时,垃圾收集器似乎与它发生了冲突。