System.AccessViolationException 在 HttpWebRequest.GetResponse

System.AccessViolationException in HttpWebRequest.GetResponse

很少抛出以下异常,在生产中连续使用 3 周大约抛出 1-5 次。 WebClient 被大量使用,在 3 周内发出了数十万个请求。服务器是 运行 Windows Server 2012 R2,安装了所有更新。该进程是64位的。发生这种情况时没有特殊情况。

Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.AccessViolationException
   at System.Collections.Concurrent.ConcurrentStack`1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].TryPop(System.__Canon ByRef)
   at System.Net.Sockets.Socket.Receive(Byte[], Int32, Int32, System.Net.Sockets.SocketFlags)
   at System.Net.Sockets.NetworkStream.Read(Byte[], Int32, Int32)
   at System.Net.FixedSizeReader.ReadPacket(Byte[], Int32, Int32)
   at System.Net.Security._SslStream.StartFrameHeader(Byte[], Int32, Int32, System.Net.AsyncProtocolRequest)
   at System.Net.Security._SslStream.StartReading(Byte[], Int32, Int32, System.Net.AsyncProtocolRequest)
   at System.Net.Security._SslStream.ProcessRead(Byte[], Int32, Int32, System.Net.AsyncProtocolRequest)
   at System.Net.TlsStream.Read(Byte[], Int32, Int32)
   at System.Net.Connection.SyncRead(System.Net.HttpWebRequest, Boolean, Boolean)
   at System.Net.ConnectStream.ProcessWriteCallDone(System.Net.ConnectionReturnResult)
   at System.Net.ConnectStream.CallDone(System.Net.ConnectionReturnResult)
   at System.Net.ConnectStream.CloseInternal(Boolean, Boolean)
   at System.Net.ConnectStream.System.Net.ICloseEx.CloseEx(System.Net.CloseExState)
   at System.Net.HttpWebRequest.EndWriteHeaders_Part2()
   at System.Net.HttpWebRequest.EndWriteHeaders(Boolean)
   at System.Net.HttpWebRequest.WriteHeadersCallback(System.Net.WebExceptionStatus, System.Net.ConnectStream, Boolean)
   at System.Net.ConnectStream.WriteHeaders(Boolean)
   at System.Net.HttpWebRequest.EndSubmitRequest()
   at System.Net.Connection.CompleteConnection(Boolean, System.Net.HttpWebRequest)
   at System.Net.Connection.CompleteStartConnection(Boolean, System.Net.HttpWebRequest)
   at System.Net.Connection.CompleteStartRequest(Boolean, System.Net.HttpWebRequest, System.Net.TriState)
   at System.Net.Connection.SubmitRequest(System.Net.HttpWebRequest, Boolean)
   at System.Net.ServicePoint.SubmitRequest(System.Net.HttpWebRequest, System.String)
   at System.Net.HttpWebRequest.SubmitRequest(System.Net.ServicePoint)
   at System.Net.HttpWebRequest.GetResponse()
   at System.Net.WebClient.GetWebResponse(System.Net.WebRequest)
   at System.Net.WebClient.DownloadBits(System.Net.WebRequest, System.IO.Stream, System.Net.CompletionDelegate, System.ComponentModel.AsyncOperation)
   at System.Net.WebClient.DownloadDataInternal(System.Uri, System.Net.WebRequest ByRef)
   at System.Net.WebClient.DownloadString(System.Uri)
   at Company.Code.Method3(System.String)
   at System.Threading.Tasks.Parallel+<>c__DisplayClass42_0`2[[System.Collections.Generic.KeyValuePair`2[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].<PartitionerForEachWorker>b__1()
   at System.Threading.Tasks.Task.InnerInvokeWithArg(System.Threading.Tasks.Task)
   at System.Threading.Tasks.Task+<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(System.Object)
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(System.Threading.Tasks.Task ByRef)
   at System.Threading.Tasks.Task.ExecuteEntry(Boolean)
   at System.Threading.Tasks.ThreadPoolTaskScheduler.TryExecuteTaskInline(System.Threading.Tasks.Task, Boolean)
   at System.Threading.Tasks.TaskScheduler.TryRunInline(System.Threading.Tasks.Task, Boolean)
   at System.Threading.Tasks.Task.InternalRunSynchronously(System.Threading.Tasks.TaskScheduler, Boolean)
   at System.Threading.Tasks.Parallel.PartitionerForEachWorker[[System.Collections.Generic.KeyValuePair`2[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]](System.Collections.Concurrent.Partitioner`1<System.Collections.Generic.KeyValuePair`2<System.__Canon,Int32>>, System.Threading.Tasks.ParallelOptions, System.Action`1<System.Collections.Generic.KeyValuePair`2<System.__Canon,Int32>>, System.Action`2<System.Collections.Generic.KeyValuePair`2<System.__Canon,Int32>,System.Threading.Tasks.ParallelLoopState>, System.Action`3<System.Collections.Generic.KeyValuePair`2<System.__Canon,Int32>,System.Threading.Tasks.ParallelLoopState,Int64>, System.Func`4<System.Collections.Generic.KeyValuePair`2<System.__Canon,Int32>,System.Threading.Tasks.ParallelLoopState,System.__Canon,System.__Canon>, System.Func`5<System.Collections.Generic.KeyValuePair`2<System.__Canon,Int32>,System.Threading.Tasks.ParallelLoopState,Int64,System.__Canon,System.__Canon>, System.Func`1<System.__Canon>, System.Action`1<System.__Canon>)
   at System.Threading.Tasks.Parallel.ForEachWorker[[System.Collections.Generic.KeyValuePair`2[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]](System.Collections.Generic.IEnumerable`1<System.Collections.Generic.KeyValuePair`2<System.__Canon,Int32>>, System.Threading.Tasks.ParallelOptions, System.Action`1<System.Collections.Generic.KeyValuePair`2<System.__Canon,Int32>>, System.Action`2<System.Collections.Generic.KeyValuePair`2<System.__Canon,Int32>,System.Threading.Tasks.ParallelLoopState>, System.Action`3<System.Collections.Generic.KeyValuePair`2<System.__Canon,Int32>,System.Threading.Tasks.ParallelLoopState,Int64>, System.Func`4<System.Collections.Generic.KeyValuePair`2<System.__Canon,Int32>,System.Threading.Tasks.ParallelLoopState,System.__Canon,System.__Canon>, System.Func`5<System.Collections.Generic.KeyValuePair`2<System.__Canon,Int32>,System.Threading.Tasks.ParallelLoopState,Int64,System.__Canon,System.__Canon>, System.Func`1<System.__Canon>, System.Action`1<System.__Canon>)
   at System.Threading.Tasks.Parallel.ForEach[[System.Collections.Generic.KeyValuePair`2[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]](System.Collections.Generic.IEnumerable`1<System.Collections.Generic.KeyValuePair`2<System.__Canon,Int32>>, System.Threading.Tasks.ParallelOptions, System.Action`1<System.Collections.Generic.KeyValuePair`2<System.__Canon,Int32>>)
   at Company.Code.Method2(xxx)
   at System.Threading.Tasks.Parallel+<>c__DisplayClass17_0`1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].<ForWorker>b__1()
   at System.Threading.Tasks.Task.InnerInvokeWithArg(System.Threading.Tasks.Task)
   at System.Threading.Tasks.Task+<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(System.Object)
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(System.Threading.Tasks.Task ByRef)
   at System.Threading.Tasks.Task.ExecuteEntry(Boolean)
   at System.Threading.Tasks.ThreadPoolTaskScheduler.TryExecuteTaskInline(System.Threading.Tasks.Task, Boolean)
   at System.Threading.Tasks.TaskScheduler.TryRunInline(System.Threading.Tasks.Task, Boolean)
   at System.Threading.Tasks.Task.InternalRunSynchronously(System.Threading.Tasks.TaskScheduler, Boolean)
   at System.Threading.Tasks.Parallel.ForWorker[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]](Int32, Int32, System.Threading.Tasks.ParallelOptions, System.Action`1<Int32>, System.Action`2<Int32,System.Threading.Tasks.ParallelLoopState>, System.Func`4<Int32,System.Threading.Tasks.ParallelLoopState,System.__Canon,System.__Canon>, System.Func`1<System.__Canon>, System.Action`1<System.__Canon>)
   at System.Threading.Tasks.Parallel.ForEachWorker[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]](System.Collections.Generic.IEnumerable`1<System.__Canon>, System.Threading.Tasks.ParallelOptions, System.Action`1<System.__Canon>, System.Action`2<System.__Canon,System.Threading.Tasks.ParallelLoopState>, System.Action`3<System.__Canon,System.Threading.Tasks.ParallelLoopState,Int64>, System.Func`4<System.__Canon,System.Threading.Tasks.ParallelLoopState,System.__Canon,System.__Canon>, System.Func`5<System.__Canon,System.Threading.Tasks.ParallelLoopState,Int64,System.__Canon,System.__Canon>, System.Func`1<System.__Canon>, System.Action`1<System.__Canon>)
   at System.Threading.Tasks.Parallel.ForEach[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]](System.Collections.Generic.IEnumerable`1<System.__Canon>, System.Threading.Tasks.ParallelOptions, System.Action`1<System.__Canon>)
   at Company.Code.Method1(xxx)

Exception Info: System.Reflection.TargetInvocationException
   at System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Object[], System.Signature, Boolean)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(System.Object, System.Object[], System.Object[])
   at System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)
   at Hangfire.Server.CoreBackgroundJobPerformer.InvokeMethod(Hangfire.Server.PerformContext, System.Object, System.Object[])
   at Hangfire.Server.CoreBackgroundJobPerformer.Perform(Hangfire.Server.PerformContext)
   at Hangfire.Server.BackgroundJobPerformer+<>c__DisplayClass8_0.<PerformJobWithFilters>b__0()
   at Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(Hangfire.Server.IServerFilter, Hangfire.Server.PerformingContext, System.Func`1<Hangfire.Server.PerformedContext>)
   at Hangfire.Server.BackgroundJobPerformer.InvokePerformFilter(Hangfire.Server.IServerFilter, Hangfire.Server.PerformingContext, System.Func`1<Hangfire.Server.PerformedContext>)
   at Hangfire.Server.BackgroundJobPerformer.PerformJobWithFilters(Hangfire.Server.PerformContext, System.Collections.Generic.IEnumerable`1<Hangfire.Server.IServerFilter>)
   at Hangfire.Server.BackgroundJobPerformer.Perform(Hangfire.Server.PerformContext)
   at Hangfire.Server.Worker.PerformJob(Hangfire.Server.BackgroundProcessContext, Hangfire.Storage.IStorageConnection, System.String)
   at Hangfire.Server.Worker.Execute(Hangfire.Server.BackgroundProcessContext)
   at Hangfire.Server.AutomaticRetryProcess.Execute(Hangfire.Server.BackgroundProcessContext)
   at Hangfire.Server.InfiniteLoopProcess.Execute(Hangfire.Server.BackgroundProcessContext)
   at Hangfire.Server.ServerProcessExtensions.RunProcess(Hangfire.Server.IServerProcess, Hangfire.Server.BackgroundProcessContext)
   at System.Threading.Tasks.Task.Execute()
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(System.Threading.Tasks.Task ByRef)
   at System.Threading.Tasks.Task.ExecuteEntry(Boolean)
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
   at System.Threading.ThreadHelper.ThreadStart(System.Object)

有人知道为什么会发生这种情况吗?

我想我可能是无意中找到了这个问题的答案。尚未确认,但值得一试。

在跨应用程序的多个线程中,我根据线程需要将不同的 ServicePointManager 属性分配给不同的值。例如:

Thread A:
void MakeCallToX {
    System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    WebClient.DownloadString("https://x");
}

Thread B:
void MakeCallToY {
    System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;
    WebClient.DownloadString("https://y");
}

可能碰巧这些方法是并行调用的。 在应用程序启动时设置 System.Net.ServicePointManager 属性(不仅是 SecurityProtocol)似乎是唯一的解决方案。