1

我有 WCF 单实例服务,它使用AsterNET库和自定义 Windows 服务中的主机。当任何客户端连接到 WCF 服务并尝试通过 AsterNET AMI 向星号发送任何命令时,我收到异常:

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

如果我在控制台应用程序中托管相同的 WCF dll,所有工作都没有任何问题。那么,任何人都知道,什么处理 NetworkStream 以及如何解决这个问题?

WindowsService WCF 主机代码:

    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;
            }
      }
}

WCF 服务的某些部分:

[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.
        }
    }
}
4

0 回答 0