我尝试构建一个简单的async net tcp wcf工具,它将打开连接,发送命令,接收答案(一个包含0-10个字符串句子的List),关闭连接。
问题是,我总是进入(自托管)服务端 - 无论我尝试什么 - “由于线程退出或应用程序请求,I / O操作已中止”,在客户端当然有相应的错误,如“现有连接被远程主机关闭”和超时等等。
我过去几天尝试过很多但是我无法摆脱它。
客户端(在.NET 4.0上运行,每秒调用一次):
void callservice(string mykey) {
ServiceReference1.Client c = new ServiceReference1.Client();
c.GetDataCompleted += c_GetDataCompleted;
try {
c.GetDataAsync(mykey);
}
catch (FaultException aa)
{
c.Abort();
}
}
private void c_GetDataCompleted(object sender, ServiceReference1.GetDataCompletedEventArgs e)
{
ServiceReference1.Client c = (ServiceReference1.Client)sender;
c.GetDataCompleted -= c_GetDataCompleted;
try
{
if (e.Result != null && e.Result.Length > 0)
{
... }
c.Close();
}
catch (Exception) {
c.Abort();
}
}
服务器端(在.NET4.5上运行):
[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple,
InstanceContextMode=InstanceContextMode.PerCall,IncludeExceptionDetailInFaults=true)]
public class Service1 : IMyService
{
public async Task<List<string>> GetData(string whatkey)
{
List<string> mydatalist = new List<string>();
mydatalist= await Task.Run<List<string>>(() =>
{
...
});
return mydatalist;
}
那里出了什么问题?可能是因为它根本不与WCF有关吗?它可能是什么?
服务器端例外:
System.Net.Sockets.SocketException,System,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089 由于线程退出或应用程序请求,I / O操作已中止 在System.ServiceModel.Channels.SocketConnection.HandleReceiveAsyncCompleted() at System.ServiceModel.Channels.SocketConnection.OnReceiveAsync(Object sender,SocketAsyncEventArgs eventArgs) 在System.Net.Sockets.SocketAsyncEventArgs.FinishOperationAsyncFailure(SocketError socketError,Int32 bytesTransferred,SocketFlags flags) 在System.Net.Sockets.SocketAsyncEventArgs.CompletionPortCallback(UInt32 errorCode,UInt32 numBytes,NativeOverlapped * nativeOverlapped) 在System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode,UInt32 numBytes,NativeOverlapped * pOVERLAP) System.Net.Sockets.SocketException(0x80004005):由于线程退出或应用程序请求,I / O操作已中止 3E3
另一个有趣的事实: SVCLogs告诉我I / O Exeption在我可以在
中定义的时间跨度之后发生<connectionPoolSettings groupName="default" leaseTimeout="00:03:00"
idleTimeout="00:02:39" maxOutboundConnectionsPerEndpoint="20" />
设置。 在此示例中,它将在00:02:39之后第一次出现。 我的解释:由于那里的设置,它关闭了打开的连接,并且自从ReceiveAsync操作i.ex.以来导致异常。仍然开放。
我的问题是到目前为止为什么client.close()没有完全关闭它,为什么在调用c_getdatacompleted-event时它还没有完成?为什么操作在02:39分钟“挂出”并且没有结束?
(如果我不通过连接池设置强制关闭,如果我使用netstat i.ex.显示,我最终会有数百个打开的操作)
答案 0 :(得分:0)
异步WCF操作(AsyncPattern=true
)是使用异步编程模型实现的。也就是说,您使用两个异步操作(“BeginOperation”和“EndOeration”)实现一个操作(“Operation”)。客户端可以使用Task
(可能是FromAsync
重载)来包装这些操作
例如:
[ServiceContract]
public interface ISampleTaskAsync
{
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginDoWork(int count, AsyncCallback callback, object state);
int EndDoWork(IAsyncResult result);
}
WCF合约不会返回Task<T>
然后,在客户端上,您可以执行以下操作:
var proxy = new Services.SampleTaskAsyncClient();
object state = "This can be whatever you want it to be";
var task = Task<int>.Factory.FromAsync(proxy.BeginDoWork,
proxy.EndDoWork, 10, state);
有关详细信息,请参阅:
如果您想使用Task<T>
,我相信您不需要AsyncPattern=true
。