Daniel Kempner
Daniel Kempner

Reputation: 415

Invoke Async Funcs

I've made a nice controller helper in my MVC project that allows me to return similarly structured result payloads when I make any ajax request. It looks like this:

    public static JsonNetResult Responsify<T>(Func<T> func)
    {
        AjaxResponse response;
        var result = new JsonNetResult
        {
            JsonRequestBehavior = JsonRequestBehavior.AllowGet
        };

        try
        {
            var resp = func();
            response = AjaxResponse.SuccessResponse(resp);
            result.Data = response;
        }
        catch (Exception e)
        {
            response = AjaxResponse.ErrorResponse(e.Message);
            result.Data = response;
        }

        return result;
    }

and it gets used like this:

    [HttpPost]
    public JsonNetResult Link(LinkInstruction instruction)
    {
        return ControllerHelper.Responsify(() => _linkHandler.Link(instruction));
    }

where _linkHandler.Link is not async.

My issue is I have some async handlers that I would like to invoke using this pattern and I can't figure out how to await the function. I've tried Task.Factory.StartNew as well as wrapping the lambda in async/await and I can't quite figure it out.

Upvotes: 4

Views: 4875

Answers (1)

Ant P
Ant P

Reputation: 25221

Create a version of Responsify - call it ResponsifyAsync - that specifies that the passed Func must return a Task<T> (therefore meaning you can await it):

public async static JsonNetResult ResponsifyAsync<T>(Func<Task<T>> func)
{
    ...
}

This would do much what your current function does, but would await func() instead of just executing it.

You must then pass a Func delegate that returns a Task to this method. When calling an async library in the delegate, since the async method you're calling already returns a Task, this will simply take the form:

var x = await ResponsifyAsync(() => _someClass.MyMethodAsync(someParameter));

Or, if the method is parameterless...

var x = await ResponsifyAsync(_someclass.MyMethodAsync);

I'll let you flesh out the method but this format should set you off on the right lines.

Upvotes: 4

Related Questions