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

问题描述 投票:0回答:1

我尝试构建一个简单的异步net 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.HandleReceiveAsyncCompleted() 在 System.ServiceModel.Channels.SocketConnection.OnReceiveAsync(对象发送者,SocketAsyncEventArgs eventArgs) 在 System.Net.Sockets.SocketAsyncEventArgs.FinishOperationAsyncFailure(SocketError socketError,Int32 bytesTransferred,SocketFlags 标志) 在 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 异常发生在我可以在

中定义的时间跨度之后
<connectionPoolSettings groupName="default" leaseTimeout="00:03:00" 
idleTimeout="00:02:39" maxOutboundConnectionsPerEndpoint="20" />

设置。 在此示例中,它将在 00:02:39 之后第一次发生。 我的解释:它会由于那里的设置而关闭打开的连接,并导致自 ReceiveAsync 操作(即 ReceiveAsync 操作)以来出现异常。仍然开放。

到目前为止,我的问题是为什么 client.close() 没有完全关闭它,为什么在调用 c_getdatacompleted-event 时它还没有完成?为什么操作“挂”了02:39分钟还没有结束?

(如果我不通过连接池设置强制关闭,如果我使用 netstat i.ex 来显示,我最终会得到数百个打开操作)

c# wcf exception io
1个回答
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

© www.soinside.com 2019 - 2024. All rights reserved.