7

我创建了一个托管在 IIS 和 wcf 客户端中的简单 wcf 服务,并发现当你从 wcf 服务中捕获一个 FaultException 然后调用 client.Abort() 来释放会话(如微软示例所说)它不会释放会议并在第 11 次通话时挂断。

这是示例:

Wcf 服务:

[ServiceContract]  
public interface IService1
{
    [OperationContract]
    string GetData(int value);
}


public class Service1 : IService1
{
    public string GetData(int value)
    {
        throw new FaultException("Exception is here");

        return string.Format("You entered: {0}", value);
    }
}

客户:

class Program
{
    static void Main(string[] args)
    {
        Service1Client client = null;          

        for(int i = 0; i < 15; i++)
        {
            try
            {
                client = new Service1Client();
                client.GetData(100);                   
            }
            catch (TimeoutException timeoutEx)
            {
                Console.WriteLine(timeoutEx);
                client.Abort();
            }
            catch (FaultException faultEx)
            {
                Console.WriteLine(faultEx);
                client.Abort();
            }
            catch (CommunicationException commEx)
            {
                Console.WriteLine(commEx);
                client.Abort();
            }
      }  
   }              

}

但是,如果您将 client.Abort() 替换为 client.Close() 以获得 catch(FaultException ),那么一切都会像魅力一样工作,并且在第 11 次调用 wcf-service 方法后没有锁定。

为什么会这样?为什么在捕获 FaultException 后 Abort() 方法不清理会话?

4

2 回答 2

6

两件事情:

  • Abort()应在通信通道处于故障状态时使用。UsingClose()使客户端尝试与服务通信,告诉它关闭服务实例,如果你愿意的话。如果通信通道处于故障状态,则意味着无法从客户端到服务进行通信。在这种情况下,您应该调用Abort()以便至少关闭客户端。服务实例/会话在服务器上仍然是活动的(因为两者之间没有通信),并且会一直保持到实例超时发生。如果你调用Close()了一个有故障的通道,它会抛出更多的错误。
  • 您的服务正在抛出FaultException. 这并不意味着通信通道将进入故障状态。即您仍然可以使用同一个客户端拨打电话。因此,在您的示例中,您不应该调用Abort().

tl; dr Abort()仅关闭客户端。服务实例/会话仍然存在。

您可以使用以下命令检查通信通道的状态:

ICommunicationObject comObj = ((ICommunicationObject)client);
if(comObj.State == CommunicationState.Faulted)
   client.Abort();
else
   client.Close();
于 2012-03-01T19:24:29.847 回答
2

您是否尝试过这种方式,我用它来调用 WCF?

class Program
{
static void Main(string[] args)
{
    for(int i = 0; i < 15; i++)
    {
        using Service1Client client = new Service1Client()
        {
        try
        {
            client.GetData(100);                   
        }
        catch (TimeoutException timeoutEx)
        {
            Console.WriteLine(timeoutEx);
            client.Abort();
        }
        catch (FaultException faultEx)
        {
            Console.WriteLine(faultEx);
            client.Abort();
        }
        catch (CommunicationException commEx)
        {
            Console.WriteLine(commEx);
            client.Abort();
        }
        finally
        {
            client.Close();
        }
        }
  }  
}              
于 2011-09-27T17:54:35.457 回答