U4-5208 - RenderActionInvoker needs to be able to run async so needs to inherit from AsyncControllerActionInvoker

Created by Shannon Deminick 10 Jul 2014, 07:01:11 Updated by Timo 12 Nov 2015, 13:48:27

Relates to: U4-7399

Without this it basically means that any umbraco controller using this action invoker like Surface Controllers, etc... cannot execute with async code without a work around.

Otherwise you'll end up with the string output from your action:

System.Threading.Tasks.Task`1[System.Web.Mvc.ActionResult]

See: http://stackoverflow.com/questions/23006976/async-controller-action-with-umbraco-7-returns-string/23033649#23033649

Comments

Shannon Deminick 11 Jul 2014, 04:02:01

I've added a work around while we wait till this new version is out, see the stack overflow thread above


Dan Mann 23 Feb 2015, 09:22:08

Hi Shannon

A site I'm building on Umbraco 7.21 is still experiencing this issue, but only on any custom controller which inherits RenderMvcController (i.e. this issue affects route hijacking still).

I'm using Umbraco.Identity, which has the workaround in it already, so SurfaceControllers are able to do async actions. However any async Action on a RenderMvcController implementation still just dumps Task.ToString() to the response. Worse still if I attempt to use Task.Wait() within a synchronous action it deadlocks. I think the latter may be an ASP.NET problem rather than specifically an Umbraco problem. The net result is that I can't make any calls to an async web API from within a RenderMvcController action, not even by wait()ing for the result.

Do you have any advice on making the workaround "stick" for RenderMvcControllers? Currently I'm having my main page content load via an AJAX call to a SurfaceController action to work around this limitation, but that's not really ideal.

Thanks

Dan


Shannon Deminick 23 Feb 2015, 13:11:14

Hi, if you have repeatable steps please open a different issue. We are definitely setting the action invoker for RenderMvcController to RenderActionInvoker which is AsyncControllerActionInvoker which happens in the RenderControllerFactory. If you have your own factory or are using IoC in some way, potentially that might be your issue. We don't use custom action invokers for SurfaceControllers, they've always worked with any async stuff OOTB.

Calling Wait() or Result() from inside of a controller that is not async from top to bottom will generally always cause a deadlock if you are not ConfiguringAwait(false) ... in most cases. Good resources here about that:

http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html http://blog.stephencleary.com/2012/02/async-and-await.html https://msdn.microsoft.com/en-us/magazine/jj991977.aspx


Kieron McIntyre 17 Oct 2015, 13:56:26

I've been able to reproduce this issue in custom controllers and have raised it here http://issues.umbraco.org/issue/U4-7270


Priority: Normal

Type: Bug

State: Fixed

Assignee: Shannon Deminick

Difficulty: Normal

Category:

Backwards Compatible: True

Fix Submitted:

Affected versions: 6.0.0, 6.1.0, 7.0.0, 7.1.0, 6.0.1, 6.0.2, 6.0.3, 6.0.4, 6.1.1, 6.0.6, 6.0.5, 6.0.7, 6.1.2, 6.1.3, 6.1.4, 6.1.5, 6.1.6, 7.0.1, 7.0.2, 7.0.3, 7.0.4, 7.1.1, 7.1.2, 7.1.3, 6.2.1, 7.1.4

Due in version: 7.1.5, 6.2.2

Sprint:

Story Points:

Cycle: