Calling a task-based asynchronous one way callback method from WCF service

北城余情 提交于 2019-12-07 21:43:04

问题


I have a WCF service which uses a callback contract to notify the clients, similar to this

public interface IClientCallback
{
    [OperationContract(IsOneWay = true)]
    void NotifySomething();
}

and the service code calling it similar to this

void NotifySomething()
{
    try
    {
        this.callback.NotifySomething();
    }
    catch (Exception ex)
    {
        // Log the exception and eat it
    }
}

Note that by design the callback notification is optional, i.e. nice to have, but not required. That's why it's marked as OneWay and the implementation eats exceptions.

Due to some misunderstanding we were thinking that would be enough for having a non blocking fire and forget method. But of course that wasn't true, so under some circumstances it's blocking for a while, which is causing problems because it's called from inside thread synchronized block. So we decided to make it asynchronous by changing the definition as follows

public interface IClientCallback
{
    [OperationContract(IsOneWay = true)]
    Task NotifySomething();
}

I have no problem with client implementation, my question is how to call it from the service. Here is what I'm thinking to do

async void NotifySomething()
{
    try
    {
        await this.callback.NotifySomething();
    }
    catch (AggregateException ex)
    {
        // Unwrap, log the exception(s) and eat it
    }
    catch (Exception ex)
    {
        // Log the exception and eat it
    }
}

Now, since everyone is saying async void is not a good practice, is it ok to use it here? What other options do I have? What is the recommended way to perform this in the WCF service context?


回答1:


The way you have written it is pretty safe as it handles the exceptions. You could also write a reusable extension method to do that so that you don't need to repeat it.

Perhaps something like this:

public static class Extensions
{
    public static void FireAndForget(this Task task)
    {
        task.ContinueWith(t => 
        {
            // log exceptions
            t.Exception.Handle((ex) =>
            {
                Console.WriteLine(ex.Message);
                return true;
            });

        }, TaskContinuationOptions.OnlyOnFaulted);
    }
}

public async Task FailingOperation()
{
    await Task.Delay(2000);

    throw new Exception("Error");
}   

void Main()
{
    FailingOperation().FireAndForget();

    Console.ReadLine();
}


来源:https://stackoverflow.com/questions/33451018/calling-a-task-based-asynchronous-one-way-callback-method-from-wcf-service

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!