我有 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.
}
}
}