Something disposes NetworkStream in WCF service hosted in Windows Service

463 views Asked by At

I have WCF single-instance service which uses AsterNET library and hosts in custom windows service. When any client connects to WCF service and try send any command to asterisk through AsterNET AMI I receive exception:

System.ObjectDisposedException was caught
  HResult=-2146232798
  Message=Cannot access a disposed object.
Object name: 'System.Net.Sockets.NetworkStream'.
  Source=System
  ObjectName=System.Net.Sockets.NetworkStream
  StackTrace:
       at System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset, Int32 size)
       at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder)
       at System.IO.StreamWriter.Write(String value)
       at AsterNET.Manager.ManagerConnection.sendToAsterisk(String buffer) in e:\Projects\Codeplex\AsterNET\Asterisk.2013\Asterisk.NET\Manager\ManagerConnection.cs:line 1967
       at AsterNET.Manager.ManagerConnection.SendToAsterisk(ManagerAction action, String internalActionId) in e:\Projects\Codeplex\AsterNET\Asterisk.2013\Asterisk.NET\Manager\ManagerConnection.cs:line 1959
       at AsterNET.Manager.ManagerConnection.SendAction(ManagerAction action, ResponseHandler responseHandler) in e:\Projects\Codeplex\AsterNET\Asterisk.2013\Asterisk.NET\Manager\ManagerConnection.cs:line 1809
       at AsterNET.Manager.ManagerConnection.SendAction(ManagerAction action, Int32 timeOut) in e:\Projects\Codeplex\AsterNET\Asterisk.2013\Asterisk.NET\Manager\ManagerConnection.cs:line 1780
       at AsteriskWCFLib.AsteriskWCFService.ExecuteOriginate(String phoneNumber, String account, String queue, String extenNumber, String queuePass) in c:\svn\work\Asterisk Proxy\AsteriskWCFLib\AsteriskWCFService.cs:line 208

And if I host same WCF dll in console application all works without any problems.. So, anyone knows, what disposes NetworkStream and how I can fix this?

WindowsService WCF host code:

    public partial class AsteriskWinSvc : ServiceBase
    {
        public AsteriskWinSvc()
        {
            InitializeComponent();
            ServiceName = "AsteriskWinSvc";
        }
        static ServiceHost _serviceHost = null;

        protected override void OnStart(string[] args)
        {
            if (_serviceHost != null)
            {
                _serviceHost.Close();
            }
            _serviceHost = new ServiceHost(new AsteriskWCFService());
            ((AsteriskWCFService)_serviceHost.SingletonInstance).Init();

            _serviceHost.Open();
        }

        protected override void OnStop()
        {
            if (_serviceHost != null)
            {
                _serviceHost.Close();
                _serviceHost = null;
            }
      }
}

Some parts of WCF service:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class AsteriskWCFService : IAsteriskServiceInbound, IDisposable
{
    private static Dictionary<string, IAsteriskServiceCallback> ClientsList =
        new Dictionary<string, IAsteriskServiceCallback>();

    private ManagerConnection _ami;
    public void JoinQueue(string phone, string userName, string queueNumber, string queuePass)
    {
        var registeredUser = OperationContext.Current.GetCallbackChannel<IAsteriskServiceCallback>();
            var flatLogger = Logger.GetInstance(LoggerType.FlatFile, ConfigurationManager.AppSettings["flatfiledebug"], "AsteriskWCF");
            if (ClientsList.ContainsKey(phone))
                ClientsList.Remove(phone);
            ClientsList.Add(phone, registeredUser);

            var newTask = Task.Factory.StartNew(() =>
            {
                bool result = false;
                try
                {
                    result = ExecuteOriginate(phone, userName, queueNumber, "9004", queuePass).IsSuccess();
                }
                catch (Exception ex)
                {

                    flatLogger.LogWarningMessage(ex.Message);
                }
                finally
                {
                    if (result)
                    {

                        ClientsList[phone].NotifyUserOriResult(true);
                    }
                    else
                    {
                        ClientsList[phone].NotifyUserOriResult(false);
                    }
                }
            });
    }
    public void Init()
    {
        ConnectToAsterisk(Settings.Default.Host, Settings.Default.Port, Settings.Default.AMI_log,
            Settings.Default.AMI_pass);
    }


    private ManagerResponse ExecuteOriginate(string phoneNumber, string account, string queue, string extenNumber, string queuePass)
    {
        var oa = new OriginateAction
        {
            Channel = string.Format("Local/{0}@from-internal/n", phoneNumber),
            Context = "from-internal",
            Exten = extenNumber,
            Priority = "1",
            CallerId = string.Format("CCM-{0}", phoneNumber),
            Variable = string.Format("varCallID={0},varUserID={1},varQueueID={2},varPassOP={3}", phoneNumber, account, queue, queuePass),
            Timeout = 30000
        };
        try
        {
            return _ami.SendAction(oa, 30000);
        }
        catch (Exception ex)
        {
            return new ManagerResponse { Response = "Error" };//Here I've got exception for example.
        }
    }
}
0

There are 0 answers