2010-02-15 31 views
8

De mi comprensión de .NET, si uso un BackgroundWorker y tienen un controlador de eventos para RunWorkerCompleted, el controlador de eventos se ejecutará en el mismo hilo en el que fue llamado RunWorkerAsync. Si, en cambio, uso BeginInvoke en un delegado para ejecutar un método de forma asincrónica y paso un parámetro AsyncCallback a BeginInvoke, ¿hay alguna forma de que especifique que la devolución de llamada se ejecuta en el mismo subproceso que llamó a BeginInvoke o, en realidad, a un hilo arbitrario? Según entiendo, la devolución de llamada se ejecuta en el siguiente subproceso disponible del grupo de subprocesos. Está bien, pero ¿hay alguna manera de ejecutar código en AsyncCallback en cualquier hilo que quiera? Sé que puede usar BeginInvoke en un formulario o control y hacer código dentro de la ejecución de devolución de llamada en el hilo que creó el elemento UI. ¿Pero qué ocurre si quiero ejecutar código en un hilo que no sea UI sin formularios o controles?¿Se puede especificar el hilo en el que se ejecuta AsyncCallback cuando se utiliza delegate.BeginInvoke?

Respuesta

6

En el subproceso que desea utilizar como destino para su operación asincrónica, la propiedad CurrentDispatcher es un objeto System.Threading.Dispatcher que se puede usar para forzar una devolución de llamada para ejecutar en ese subproceso.

Esta es la clase base de que la clase de control utiliza para implementar BeginInvoke.

Han surgido preguntas sobre el uso de esto con los formularios de Windows. No creo que esto sea un problema, aunque si tienes un formulario, entonces form.BeginInvoke es una mejor opción. Parece que tanto la forma como WPF usan la misma clase base para manejar la invocación. http://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext.aspx

+0

+1 para la propiedad CurrentDispatcher ... – IAbstract

+0

System.Windows.Threading.Dispatcher es específica de WPF y no tiene cualquier cosa que tenga que ver con el hilo donde se llama a AsyncCallback de Delegate.BeginInvoke. –

+1

@Jeff: proporciona un método BeginInvoke alternativo para permitir la orientación de la devolución de llamada. Por lo que puedo decir, esto es lo que realmente quiere y simplemente confundió su terminología al hacer la pregunta. –

0

El subproceso será siempre un subproceso de grupo de subprocesos y nunca será un subproceso de UI.

Por cierto, C# no tiene ninguna clase BackgroundWorker. .NET lo hace.

+0

Gracias. No quise dar a entender que BackgroundWorker era específico de C#. Lo saqué. – YWE

0

Hice una búsqueda y yo terminamos en Jon Skeet's site. Es muy informativo sobre cómo funciona el subprocesamiento con delegados asincrónicos y devoluciones de llamada. Recomiendo esta lectura.

5

Delegate.BeginInvoke siempre se ejecutará el delegado en el ThreadPool y la AsyncCallback se llama en el mismo subproceso que ejecuta el delegado.

Su única opción es volver a invocar la devolución de llamada en su hilo específico:

AsyncCallback = delegate (IAsyncResult ar) 
{ 
    wathever.BeginInvoke(delegate 
    { 
     // Do your stuff... 
    }; 
}; 
+0

¿Quiere decir que se llama al AsyncCallback en el mismo hilo que llamó BeginInvoke? Esto parece contrario a lo que entiendo del artículo de documentación de MSDN titulado "Llamando a métodos sincrónicos asíncronamente" (http://msdn.microsoft.com/en-us/library/2e08f6yc.aspx) donde dice "Si el hilo que inicia el la llamada asincrónica no necesita ser el hilo que procesa los resultados, puede ejecutar un método de devolución de llamada cuando finaliza la llamada. " – YWE

+4

No, quise decir que cuando llama a Delegate.BeginInvoke desde el subproceso A, este delegado se ejecuta en un subproceso B en el ThreadPool y luego se llama al AsyncCallback en el subproceso B. –

+1

Es cierto. Acabo de verificarlo. No creo que lo aclaren en la documentación de MSDN. – YWE

Cuestiones relacionadas