today I’ll talk about one issue with Lync Client API you already might come across in doing initialization of LyncClient object in your custom app.
The problem appears when you handle the LyncClient object reference and, for some reason (albeight communicator is gracefully ended or focibly shut down), the object become ‘unavailable’. If you subscribed to the ClientDisconnected event, it will be fired now. This would be the indication to try to initialize the object again when Lync is back, since the reference becomes useless. Actually, if you try to initialize the object again with:
m_lyncClient = null;
m_lyncClient = LyncClient.GetClient();
you will get either: an exception of one of the lync’ defined types (e.g. ClientNotFoundException), or: the client object will go into the Invalid state. This latter case seems to be the problem to handle.
This case arises when you handle Lync client object on another threads (i.e. worker threads), which is quite normal, since polling for Lync connection via timer and/or operating with Lync client API via wrapper class acting like a ‘model’ (in case of MVVM) is usual thing to do. In this case, Lync Client API doesn’t know how to find the right reference and it just goes into invalid state. The resolution is to find the right thread from where the original reference is created, and this would be in most cases, the very main (UI) thread. If you use Lync controls or start to call the API from some UI element, this would be the thread from where you started to use the API. So, the only thing to do in this case, is to check for the invalid state (a suitable place would be in your re-initialization code) and dispose all resources bound to API, together with the object itself (it doesn’t have a Dispose method, so you just set it to a null value):
try
{
m_lyncClient = null;
m_lyncClient = LyncClient.GetClient();
// we must check the invalid state, since this is the indication of lost reference and malicious lync object
if (m_lyncClient.State == ClientState.Invalid)
{
// Note: disposing of the original reference must happen on the main thread!
App.Current.Dispatcher.Invoke(new Action(() => {
// release main Lync API object (next time, correct reference will be created)
Dispose();
}));
}
else
{
SubscribeToLyncEvents();
}
}
catch (ClientNotFoundException cnfEx)
{
…
}
catch (COMException cEx)
{
…
}
catch (NullReferenceException nrEx)
{
…
}
After you’ve done that, initialize the API object again and you’ll be good to go.
Kind regards,
Ratko.