gpt4 book ai didi

.net - Visual Studio 生成的 Web 服务客户端线程安全吗?

转载 作者:行者123 更新时间:2023-12-02 04:33:55 25 4
gpt4 key购买 nike

我们在我们的一个项目中创建了一个服务引用。

现在我们在应用程序启动时创建一个实例。此外,当应用程序统计时,我们添加 Service.Method1Completed 的事件处理程序, Service.Method2Completed等等。

然后,对于特定事件,我们调用 Service.Method1Async , Service.Method2Async等等。请注意,这些调用是由不同的线程发出的。

但在某些计算机上,事件处理程序永远不会被触发,因此我们开始检查 FirstChanceExceptions ,事实证明,当这种情况发生时,会出现以下 FirstChanceExceptions发生。

System.Net.Sockets.SocketException An invalid argument was supplied.
vid System.Net.Sockets.Socket.SetSocketOption(SocketOptionLevel optionLevel, SocketOptionName optionName, Int32 optionValue, Boolean silent)

System.ObjectDisposedException Cannot access a disposed object. Objectname: System.Net.Sockets.NetworkStream. vid System.Net.Sockets.NetworkStream.UnsafeBeginWrite(Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)

System.Net.WebException The request was canceled.
vid System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)

这是使用服务引用的无效方式吗?如果是的话,我如何在使用带有事件的异步方法时正确同步我的调用(请注意,我对 .net 4.0 和 VS 2010 很不满意,所以 await 不适用......)。

服务器代码:

<ServiceContract()>
Public Interface IService1

<OperationContract()>
Function GetData(ByVal value As Integer) As String

End Interface

<ServiceBehavior(ConcurrencyMode:=ConcurrencyMode.Multiple, InstanceContextMode:=InstanceContextMode.Single, UseSynchronizationContext:=False)>
Public Class Service1
Implements IService1

Public Sub New()
End Sub

Public Function GetData(ByVal value As Integer) As String Implements IService1.GetData
Return String.Format("You entered: {0}", value)
End Function

End Class

服务器配置:

<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceThrottling maxConcurrentCalls="1000" maxConcurrentSessions="1000" maxConcurrentInstances="1000" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding>
<binaryMessageEncoding>
<readerQuotas maxArrayLength="5242880" />
</binaryMessageEncoding>
<httpTransport maxBufferPoolSize="52428800" maxReceivedMessageSize="5242880" maxBufferSize="5242880" authenticationScheme="Anonymous" />
</binding>
</customBinding>
</bindings>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>

客户端代码:

Imports System.Threading
Imports System.IO

Module Module1
Dim errorQueue As New System.Collections.Concurrent.ConcurrentBag(Of String)
Dim count As Integer

Sub Main()
AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException
AddHandler AppDomain.CurrentDomain.FirstChanceException, AddressOf AppDomain_FirstChanceException

MultipleClientInstances()
Console.WriteLine("Calls are in progress, press any key when they are done!")
Console.ReadKey()

Thread.MemoryBarrier()
errorQueue.Add("Number of requests remaining " + count.ToString())
Dim line As String = ""
Using writer As New StreamWriter("output.log")
While (errorQueue.TryTake(line))
writer.WriteLine(line)
End While
End Using
End Sub

Private Function GetClient() As ServiceReference1.Service1Client
Dim client As New ServiceReference1.Service1Client()
AddHandler client.GetDataCompleted, AddressOf client_GetDataCompleted
client.Open()
Return client
End Function

Private Sub MultipleClientInstances()
Console.WriteLine("Making calls!")
For i As Integer = 0 To 10
Dim t As New Thread(AddressOf MakeCallsWithNewClients)
t.Start()
Next
End Sub

Private Sub MakeCallsWithNewClients()
For i As Integer = 0 To 400
Interlocked.Increment(count)
Dim client As ServiceReference1.Service1Client = GetClient()
client.GetDataAsync(i, True)

While (Thread.VolatileRead(count) > 20)
Thread.Sleep(5)
End While
Next
End Sub

Private Sub client_GetDataCompleted(sender As Object, e As ServiceReference1.GetDataCompletedEventArgs)
Dim value As Integer = Interlocked.Decrement(count)
Console.WriteLine(value)

Dim client As ServiceReference1.Service1Client = CType(sender, ServiceReference1.Service1Client)
RemoveHandler client.GetDataCompleted, AddressOf client_GetDataCompleted
client.Close()
End Sub

Private Sub CurrentDomain_UnhandledException(ByVal sender As Object, ByVal e As UnhandledExceptionEventArgs)
If (e.ExceptionObject IsNot Nothing AndAlso e.ExceptionObject.GetType().IsSubclassOf(GetType(Exception))) Then
If (e.IsTerminating) Then
Console.WriteLine("Fatal exception occurred termination application, " + CType(e.ExceptionObject, Exception).ToString())
Else
Console.WriteLine("Unhandled exception occurred, " + CType(e.ExceptionObject, Exception).ToString())
End If
Else
If (e.IsTerminating) Then
Console.WriteLine("Fatal exception occurred termination application, " & e.ExceptionObject.ToString())
Else
Console.WriteLine("Unhandled exception occurred, " & e.ExceptionObject.ToString())
End If
End If
errorQueue.Add("UnhandledException: " + e.ExceptionObject.ToString())
End Sub

Private Sub AppDomain_FirstChanceException(ByVal sender As Object, ByVal e As Runtime.ExceptionServices.FirstChanceExceptionEventArgs)
Console.WriteLine("FirstChanceException: " + e.Exception.ToString())
errorQueue.Add("FirstChanceException: " + e.Exception.ToString())
End Sub
End Module

最佳答案

它们不是线程安全的(例如,ClientBase 就不是)。但它们的创建和销毁成本都很低。每个线程创建一个,甚至每个调用创建一个。无需同步。

关于.net - Visual Studio 生成的 Web 服务客户端线程安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25509112/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com