2012-03-03 13 views
5

Tengo un método que realiza llamadas asíncronas al servicio web. Algo así:Obtener el resultado del método async

public static async Task<ReturnResultClass> GetBasicResponseAsync() 
{ 
    var r = await SomeClass.StartAsyncOp(); 
    return await OtherClass.ProcessAsync(r); 
} 

Y quiero dar alternativa sincrónica:

public static ReturnResultClass GetBasicResponse() 
{ 
    return GetBasicResponseAsync().Result; 
} 

Pero bloquea en Result llamada. Porque se llama en el mismo hilo que las operaciones asincrónicas. ¿Cómo puedo obtener resultados sincrónicamente?

Gracias!

Respuesta

8

Tienes razón, si estás en una aplicación GUI, las partes de continuación de un método async se ejecutarán en el subproceso UI de forma predeterminada. Y si ejecuta la espera sincrónica para la misma tarea en el subproceso de interfaz de usuario al mismo tiempo, obtendrá un interbloqueo.

Si es su aplicación, puede resolver esto simplemente sin esperar la tarea sincrónicamente.

Si solo está escribiendo una biblioteca, puede solucionarlo usando ConfigureAwait(false). De esta forma, la parte de continuación del método no se ejecutará en el contexto capturado (el subproceso de la interfaz de usuario en las aplicaciones de GUI), sino en un subproceso de ThreadPool.

public static async Task<ReturnResultClass> GetBasicResponseAsync() 
{ 
    var r = await SomeClass.StartAsyncOp().ConfigureAwait(false); 
    return await OtherClass.ProcessAsync(r).ConfigureAwait(false); 
} 

Por supuesto, la solución ideal es no utilizar operaciones síncronas en sus aplicaciones GUI y uso ConfigureAwait() en su biblioteca, para que otros puedan utilizar versiones sincrónicas de los métodos, si así lo desean.

+0

Gracias! ¿'ConfigureAwait' afectará a los clientes asíncronos de mi lib? Quiero decir, ¿las operaciones de sincronización seguirán siendo asincrónicas, o se ejecutarán en otro hilo para todos los clientes? – gor

+0

Sí, afectará a los clientes asincrónicos también, pero de una manera que debería estar bien. Las operaciones asíncronas se mantendrán sincronizadas, es solo que la parte de continuación del código que usa 'ConfigureAwait()' no se ejecutará en el subproceso de la interfaz de usuario. Pero cualquier código asíncrono en métodos que comiencen en el subproceso de UI permanecerá allí (a menos que use 'ConfigureAwait()' también). – svick

Cuestiones relacionadas