I implemented a client-server application for chatting with WCF. And i have a callback for broadcasting. It was working properly until i changed some functions. I was using my dataset fix data. It was initialized on my server and was used. I implemented an XML parser mechanism and then i'm getting an error like that:
Cannot access a disposed object. Object name: 'System.ServiceModel.InstanceContext'.
I'm using my service like that:
System.ServiceModel.InstanceContext context = new System.ServiceModel.InstanceContext(this.cb);
this._client = new WCFDevComServiceClient(context);
and then i'm openning this._client just one time and i'm using this object for my each call. (I don't close this object anytime.)
If i open before each call and then close it, then it's working. But in this case my callback function doesn't work. And i can't broadcast. So I can't close my client object.
Do you have any further information about this error? Or any fix suggestion?
My Service Codes:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class WCFDevComService : IWCFDevComService
{
private const string deviceXmlPath = @"D:\MyDocuments\Visual Studio 2015\Projects\WCFBroadcastorService\WCFDeviceCom\WCFDeviceCom_Service\bin\Devices.xml";
private const string userXmlPath = @"D:\MyDocuments\Visual Studio 2015\Projects\WCFBroadcastorService\WCFDeviceCom\WCFDeviceCom_Service\bin\Users.xml";
private DbOperations.DbOperations dbOperator = new DbOperations.DbOperations();
private static List<User> UserCollection = new List<User>();
private static Dictionary<string, IWCFDevComServiceBroadcastorCallback> clients = new Dictionary<string, IWCFDevComServiceBroadcastorCallback>();
private static object locker = new object();
private List<Device> deviceCollection = new List<Device>();
public bool LoginToServer(string clientName)
{
bool retVal = false;
if (clientName != "")
{
retVal = CheckUserName(clientName);
if (true == retVal)
{
try
{
IWCFDevComServiceBroadcastorCallback callback =
OperationContext.Current.GetCallbackChannel<IWCFDevComServiceBroadcastorCallback>();
if (clients.Keys.Contains(clientName))
clients.Remove(clientName);
clients.Add(clientName, callback);
}
catch (Exception ex)
{
throw;
}
}
}
return retVal;
}
private bool CheckUserName(string clientName)
{
lock (locker)
{
UserCollection = dbOperator.QueryForGetAllUsers(userXmlPath);
foreach (var user in UserCollection)
{
if (user.m_userName.Contains(clientName))
{
return true;
}
}
return false;
}
}
public List<Device> GetAllDevicesInformation()
{
try
{
return GetInformationFromDeviceXML();
}
catch (Exception ex)
{
throw;
return null;
}
}
private List<Device> GetInformationFromDeviceXML()
{
try
{
lock (locker)
{
deviceCollection = dbOperator.QueryForGetAllDevices(deviceXmlPath);
}
return deviceCollection;
}
catch (Exception ex)
{
throw;
return null;
}
}
public int GetNumberOfDevices()
{
try
{
lock (locker)
{
//todo: GetNumberOfDevicesFromXML
return dbOperator.QueryForGetDeviceCount(deviceXmlPath);
}
}
catch (Exception ex)
{
throw;
return 0;
}
}
public Device GetDeviceInformation(int index)
{
List<Device> deviceCollection = GetInformationFromDeviceXML();
return deviceCollection[index];
}
public int BlockedDevice(int index, User user)
{
try
{
if (index < 0 && user == null)
return -1; //fail
lock (locker)
{
if (deviceCollection[index].m_state.m_state != States.Free)
return 1; // isn't free for blocking
DeviceState tmpState = new DeviceState();
tmpState.m_state = States.Locked;
tmpState.m_lockedUser = user;
deviceCollection[index].m_state = tmpState;
//todo: UpdateXML
dbOperator.QueryForUpdateDeviceStateById(deviceXmlPath, index + 1, tmpState);
//deviceCollection = GetInformationFromDeviceXML();
NotifyOtherClients(index, user);
return 0; //success
}
}
catch (Exception ex)
{
throw;
return -1;
}
}
public int FreeDevice(int index, User user)
{
try
{
if (index < 0 && user == null)
return -1; //fail
lock (locker)
{
if (deviceCollection[index].m_state.m_state != States.Locked)
return 1; // isn't locked to free
if (deviceCollection[index].m_state.m_lockedUser.m_userName != user.m_userName && user.m_userPermission != Permission.ADMIN)
return 2; // isn't right person
DeviceState tmpState = new DeviceState();
tmpState.m_state = States.Free;
tmpState.m_lockedUser = null;
deviceCollection[index].m_state = tmpState;
//todo: UpdateXML
dbOperator.QueryForUpdateDeviceStateById(deviceXmlPath, index + 1, tmpState);
//deviceCollection = GetInformationFromDeviceXML();
NotifyOtherClients(index, user);
return 0; //success
}
}
catch (Exception ex)
{
throw;
return -1;
}
}
public Permission GetPermission(string userName)
{
lock (locker)
{
foreach (var user in UserCollection)
{
if (user.m_userName == userName)
return user.m_userPermission;
}
return Permission.USER;
}
}
private void NotifyOtherClients(int index, User user)
{
try
{
var inactiveClients = new List<string>();
EventDataType eventData = new EventDataType();
eventData.ClientName = user.m_userName;
eventData.Index = index;
foreach (var client in clients)
{
if (client.Key != eventData.ClientName)
{
try
{
client.Value.BroadcastToClient(eventData);
}
catch (Exception ex)
{
inactiveClients.Add(client.Key);
}
}
}
if (inactiveClients.Count > 0)
{
foreach (var client in inactiveClients)
{
clients.Remove(client);
}
}
}
catch (Exception ex)
{
throw;
}
}
}