无论我尝试什么:由于线程退出或应用程序请求,I/O操作都已中止

本文关键字:请求 应用程序 操作 退出 什么 线程 于线程 | 更新日期: 2023-09-27 18:00:32

我尝试构建一个简单的异步网络tcp wcf工具,它将打开连接,发送命令,接收答案(一个包含0-10个字符串句子的列表),关闭连接。

问题是,无论我尝试什么,我总是在(自托管)服务端"由于线程退出或应用程序请求,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,系统,版本=4.0.0.0,区域性=中性,PublicKeyToken=b77a5c561934e089由于线程退出或应用程序请求,I/O操作已中止位于System.ServiceModel.Channels.SocketConnection.HHandleReceiveAsyncCompleted()位于System.ServiceModel.Channels.SocketConnection.OnReceiveAsync(对象发送器,SocketAsyncEventArgs事件Args)位于System.Net.SocketAsyncEventArgs.FinishOperationAsyncFailure(SocketError SocketError,Int32字节传输,SocketFlags标志)位于System.Net.SocketAsyncEventArgs.CompletionPortCallback(UInt32错误代码,UInt32 numBytes,NativeOverlapped*NativeOverlapped)在System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32错误代码,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.来显示,我最终会有数百个打开的操作)

无论我尝试什么:由于线程退出或应用程序请求,I/O操作都已中止

异步WCF操作(AsyncPattern=true)是用异步编程模型实现的。也就是说,您使用两个异步操作("BeginOperation"answers"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);

有关更多信息,请参阅:

  • http://msdn.microsoft.com/en-us/library/system.servicemodel.operationcontractattribute.asyncpattern.aspx
  • http://blogs.msdn.com/b/rjacobs/archive/2011/06/30/how-to-implement-a-wcf-asynchronous-service-operation-with-task-lt-t-gt.aspx

如果你想使用Task<T>,我相信你不需要AsyncPattern=true

相关文章: