如何处理ServiceMode il故障状态

时间:2017-03-19 17:10:14

标签: c# asp.net wcf

我已按照此示例在ASP.NET网站和C#项目之间创建通信:https://dopeydev.com/wcf-interprocess-communication/

在一段时间不活动后,服务进入故障状态,我不能再交换数据了:

  

抛出异常:' System.ServiceModel.CommunicationObjectFaultedException'在mscorlib.dll中

当我尝试从网站发送消息时会引发此异常,例如:

service.SendMessage("Hi, I'm the client");

有没有办法让服务永久启用? 它可以在局域网上工作,网页是一个控制界面,每隔几个小时就可以发送一次数据。

更新

这里是服务器配置:

using System.ServiceModel;
using System;

namespace MyProject
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class IServer : Interfaces.IService
    {
        public void Connect()
        {
            Callback = OperationContext.Current.GetCallbackChannel<Interfaces.ICallbackService>();
        }

        public static Interfaces.ICallbackService Callback { get; set; }

        public void SendMessage(string message)
        {
            MessageReceivedEventArgs args = new MessageReceivedEventArgs();
            args.json = message;
            OnMessageReceived(this, args);
        }

        public event EventHandler<MessageReceivedEventArgs> MessageReceived;
        protected virtual void OnMessageReceived(object sender, MessageReceivedEventArgs e)
        {
            MessageReceived?.Invoke(this, e);
        }
    }

    public class MessageReceivedEventArgs : EventArgs
    {
        public string json;
    }
}

2 个答案:

答案 0 :(得分:1)

由于您的服务具有单个实例,因此可以保持与其的永久连接。永久连接不好,因为它们消耗资源,但如果您真的需要它,那么您需要将receiveTimeout两侧设置为TimeSpan.Max。通过这种方式,WCF不会像现在那样关闭连接。

在您的示例代码中,您需要在客户端和服务器代码中将new NetNamedPipeBinding()替换为new NetNamedPipeBinding() { ReceiveTimeout = TimeSpan.Max }

根据服务代码,您不要假设连接的客户端超过1个(因为Callback是静态字段),但仍然要注意,如果客户端断开连接,那么Callback看起来有效,但如果你尝试发送它会抛出的东西。

答案 1 :(得分:0)

我最终得到了这段代码。它似乎有效,但我想知道它有多强大。

public bool CheckConnection()
{
    if (pipeFactory == null)
    {
        pipeFactory = new DuplexChannelFactory<IService>(new InstanceContext(_instance), new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/ipc"));
    }

    try
    {
        switch (pipeFactory.State)
        {
            case CommunicationState.Faulted:
                pipeFactory.Abort();
                pipeFactory = new DuplexChannelFactory<IService>(new InstanceContext(_instance), new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/ipc"));
                service = pipeFactory.CreateChannel();
                service.Connect();
                break;

            case CommunicationState.Closed:
                service = pipeFactory.CreateChannel();
                service.Connect();
                break;

            case CommunicationState.Created:
                service = pipeFactory.CreateChannel();
                service.Connect();
                break;
        }

    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(ex);
        throw;
    }

    return pipeFactory.State == CommunicationState.Opened;
}

更新

这不起作用。即使pipeFactory.StateOpened,在一段时间不活动后也会引发以下异常:

  

抛出异常:mscorlib.dll中的“System.ServiceModel.CommunicationObjectFaultedException”

     

System.ServiceModel.CommunicationObjectFaultedException:通信对象System.ServiceModel.Channels.ServiceChannel不能用于通信,因为它处于Faulted状态。

     

服务器堆栈跟踪:      在System.ServiceModel.Channels.CommunicationObject.ThrowIfDisposedOrNotOpen()      在System.ServiceModel.Channels.ServiceChannel.Call(String action,Boolean oneway,ProxyOperationRuntime operation,Object [] ins,Object [] outs,TimeSpan timeout)      在System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall,ProxyOperationRuntime操作)      在System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

     

在[0]处重新抛出异常:      在System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg,IMessage retMsg)      在System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&amp; msgData,Int32 type)      在Interfaces.IService.SendMessage(String message)      在_Default.Submit1(String name,String surname,String country,String email,Boolean disclaimer1,Boolean disclaimer2)中的Default.aspx.cs:第99行