0

I use the Lync SDK 2013 and want to send an instant message to a contact.

    private void SuppressIncomingConversation(Conversation conversation)
    {
        InstantMessageModality instantMessageModality = conversation.Modalities[ModalityTypes.InstantMessage] as InstantMessageModality;
        instantMessageModality.BeginSendMessage("No.", null, null);
        conversation.End();
    }

The second parameter of BeginSendMessage is a callback of type AsyncCallback.

The code above works fine but should I put conversation.End(); into the callback parameter?

How can I do this, I tried () => conversation.End() but the callback needs to take some arguments.

1 Answers1

0

The async API in the Lync Client 2013 API are a older style of the a standard C# async API.

So the API has StartXxx and a matching EndXxx for all ASYNC operations. You need to call the EndXxx when the AsyncCallback completes.

There are actually a number of ways to handle this. A common way is to provide a callback to call the EndXxx method.

e.g.

InstantMessageModality instantMessageModality = conversation.Modalities[ModalityTypes.InstantMessage] as InstantMessageModality;
instantMessageModality.BeginSendMessage("No.", ar =>
    {
        try
        {
            instantMessageModality.EndSendMessage(ar);
        }
        catch (Exception ex)
        {
            // log ex message
        }
    });

Also you may like to check that your only dealing with "audio / video calls" only... As you may be ending other types of calls...

You do this be checking that the call has a AVModality e.g.

if (conversation.Modalities.ContainsKey(ModalityTypes.AudioVideo))

Another problem is that the conversation may be in a state that can't do the async operation you want, you can test if you are allowed to do your operation with the CanInvoke method. e.g

if (conversation.Modalities.TryGetValue(ModalityTypes.InstantMessage, out var modality))
{
    if (modality is InstantMessageModality instantMessageModality && instantMessageModality.CanInvoke(ModalityAction.SendInstantMessage))
    {
        instantMessageModality.BeginSendMessage("No.", ar =>
        {
            try
            {
                instantMessageModality.EndSendMessage(ar);
            }
            catch (Exception ex)
            {
                // log ex message
            }
        }, null);
    }
}

And one last point, you can also provide a "reason" (like Busy) for declaring the call rather than using End to terminate the conversation...

e.g.

if (conversation.Modalities.TryGetValue(ModalityTypes.AudioVideo, out var modality))
{
    if (modality is AVModality avModality && avModality.CanInvoke(ModalityAction.Disconnect))
    {
        avModality.BeginDisconnect(ModalityDisconnectReason.Busy, ar =>
        {
            try
            {
                avModality.EndDisconnect(ar);
            }
            catch (Exception ex)
            {
                // log ex message
            }
        }, null);
    }
    else
    {
        // fallback
        conversation.End();
    }
}
Shane Powell
  • 13,698
  • 2
  • 49
  • 61
  • Hello again Shane, this is awesome. So if someone calls me and I use `avModality.BeginDisconnect(ModalityDisconnectReason.Busy` his call gets suppressed? –  Aug 23 '18 at 09:30
  • Disconnect method will have the same behaviour as the "end" but it provides a "reason" which is useful to the caller / lync logging. Your "BeginSendMessage" doesn't have a call to "EndSendMessage". I would also use the disconnect method after the calling EndSendMessage as well. – Shane Powell Aug 23 '18 at 17:03
  • Also, you may consider the reason DeclineEverywhere reason which will cause all your endpoints alerting to be ended. – Shane Powell Aug 23 '18 at 17:09