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