run async .net async-await parse.com ihttphandler

.net - task run async c#



Async espera del punto muerto del controlador (2)

Estoy atrapado en un punto muerto Async y no puedo encontrar la sintaxis correcta para solucionarlo. He analizado varias soluciones diferentes, pero parece que no puedo entender qué está causando el problema.

Estoy usando Parse como un backend e intento usar un controlador para escribir en la mesa. Mi controlador se ve algo así como:

public class VisitorSignupHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { //Get the user''s name and email address var UserFullName = context.Request.QueryString["name"].UrlDecode(); var UserEmailAddress = context.Request.QueryString["email"].UrlDecode(); //Save the user''s information var TaskToken = UserSignup.SaveUserSignup(UserFullName, UserEmailAddress); TaskToken.Wait(); .... } public bool IsReusable { get { return false; } } }

Entonces está llamando a mi nivel medio:

public static class UserSignup { public static async Task SaveUserSignup(string fullName, string emailAddress) { //Initialize the Parse client with the Application ID and the Windows key ParseClient.Initialize(AppID, Key); //Create the object var UserObject = new ParseObject("UserSignup") { {"UserFullName", fullName}, {"UserEmailAddress", emailAddress} }; //Commit the object await UserObject.SaveAsync(); } }

Aunque parece que esto se está estancando en Wait() . Tenía la impresión de que Wait() simplemente esperaría a que se completara la tarea y luego volvería a las operaciones normales. ¿Esto no es correcto?


Te encuentras con un problema común de interbloqueo que describo en mi blog y en un artículo reciente de MSDN .

En resumen, await por defecto que reanude su método async dentro de un "contexto" capturado, y en ASP.NET, solo se permite un subproceso en ese "contexto" a la vez. Entonces, cuando llamas a Wait , estás bloqueando un hilo dentro de ese contexto, y el await no puede ingresar a ese contexto cuando esté listo para reanudar el método async . Por lo tanto, el hilo en el contexto está bloqueado en Wait (esperando a que se complete el método async ), y el método async se bloquea a la espera de que el contexto sea libre ... punto muerto.

Para solucionar esto, debe ir "asincrono todo el camino". En este caso, use HttpTaskAsyncHandler lugar de IHttpHandler :

public class VisitorSignupHandler : HttpTaskAsyncHandler { public override async Task ProcessRequestAsync(HttpContext context) { //Get the user''s name and email address var UserFullName = context.Request.QueryString["name"].UrlDecode(); var UserEmailAddress = context.Request.QueryString["email"].UrlDecode(); //Save the user''s information var TaskToken = UserSignup.SaveUserSignup(UserFullName, UserEmailAddress); await TaskToken; .... } }


Tu problema es que estás mezclando código síncrono y asíncrono. Esto se puede hacer, pero es complicado. Su mejor opción es hacer que su manejador de http también sea asincrónico:

public class VisitorSignupHandler : HttpTaskAsyncHandler { public override async Task ProcessRequestAsync(HttpContext context) { //Get the user''s name and email address var UserFullName = context.Request.QueryString["name"].UrlDecode(); var UserEmailAddress = context.Request.QueryString["email"].UrlDecode(); //Save the user''s information await UserSignup.SaveUserSignup(UserFullName, UserEmailAddress); .. } }