Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Robert Mulder 79 posts 272 karma points c-trib
    Apr 17, 2015 @ 11:49
    Robert Mulder
    0

    Async RenderMvcController

    Is it possible to create a custom RenderMvcController, but have it be async?

    I've created my own RenderMvcController called CustomRenderMvcController and set it up as the default RenderMvcController. To add functions to this controller (I want to use a different default RenderModel) I have to override the Index() method.

    Herein lies my problem. This method is not async, so overriding it always gives me a non async method. Any async action I try to perform in this method (for instance getting something from a remote url) always has to use the sync variation.

    Am I doing something wrong here or is this just how it is?

  • Craig 10 posts 61 karma points
    Oct 12, 2015 @ 15:34
    Craig
    0

    Did you find a resolution to this? We are potentially facing the same issue.

  • Robert Mulder 79 posts 272 karma points c-trib
    Oct 13, 2015 @ 07:01
    Robert Mulder
    0

    I'm afraid not. As far as I know, when using a custom RenderMvcController you're stuck to either using the synchronous variant of a method or, if this is not available, use something like Stephen Cleary's AsyncEx to call awaitable methods from a synchronous method.

    See here for more info https://github.com/StephenCleary/AsyncEx

    Or get it from Nuget https://www.nuget.org/packages/Nito.AsyncEx/

    Ofcourse you'll lose the benefits of async mehods, but at least it works.

  • Lars-Erik Aabech 349 posts 1100 karma points MVP 8x c-trib
    Oct 13, 2015 @ 08:15
    Lars-Erik Aabech
    1

    Why not just use the methods on Task to wait in the controller?

    public class SomeRenderController : RenderMvcController
    {
        public override ActionResult Index(RenderModel model)
        {
            var mightTimeOutTask = some.AsyncMethod();
            mightTimeOutTask.Wait(TimeSpan.FromSeconds(10)); // Waits until done or continues at 10
            // TODO: Handle timeouts
            var value = mightTimeOutTask.Result; // .Result blocks until done
    
            // OR
    
            var prettyQuickResult = some.AsyncMethod().Result; // .Result blocks until done
    
            return View();
        }
    }
    
  • Robert Mulder 79 posts 272 karma points c-trib
    Oct 13, 2015 @ 08:19
    Robert Mulder
    1

    In ASP.NET you should really try to avoid using the .Wait() methods or .Result property of tasks as they are prone to cause deadlocks.

    See the blog below (incidentally also from the same Stephen) that explains why:

    http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

  • Lars-Erik Aabech 349 posts 1100 karma points MVP 8x c-trib
    Oct 13, 2015 @ 08:25
    Lars-Erik Aabech
    0

    I see. Never knew that. Although none of my stuff have ever deadlocked.

    However, as he states in his blog, adding .ConfigureAwait(false) to the second layer down should make everything safe, so my example still holds. ;)

  • Robert Mulder 79 posts 272 karma points c-trib
    Oct 13, 2015 @ 09:10
    Robert Mulder
    0

    Yeah, I haven't really been able to figure out exactly when it deadlocks and when it doesn't. I'm certain I've run into deadlock situations in the past, but seamingly similar situations wouldn't deadlock.

    So now to be safe I generally just wrap it in an AsyncEx.Run() wrapper when calling async methods from synchronous methods, which to be frank, doesn't really happens all that often anymore these days.

  • Lars-Erik Aabech 349 posts 1100 karma points MVP 8x c-trib
    Oct 13, 2015 @ 09:12
    Lars-Erik Aabech
    0

    It probably deadlocks with larger loads than we currently have where we've done this.

    I'll start adding ConfigureAwait if I do this again and hope I'm in the green. :)

Please Sign in or register to post replies

Write your reply to:

Draft