2010-08-13 23 views
8

¿Hay alguna manera de hacer que un delegado se ejecute en un hilo específico?Invocar un delegado en un hilo específico C#

Decir que tengo:

CustomDelegate del = someObject.someFunction; 
Thread dedicatedThread = ThreadList[x]; 

¿Puedo tener un fondo consistente hilo de larga data e invocar mis propios delegados en él cuando lo necesito. Tiene que ser el mismo hilo cada vez.

[Editar]

La razón por la que quiero que sea en un hilo dedicado es tiempo es que me InTen para ejecutar el delegado en ella y suspender el hilo después de y milisegundos, y reanudar el hilo cuando corro otro delegado en él. Veo que esto no es posible. Tendré una cola delegada y dejaré que la función principal del hilo se lea y ejecute desde allí.

Para aclarar con un ejemplo concreto, tengo un sistema de juego con un montón de hilos de jugador. Me gustaría que cada playerthread ejecute controladores de eventos para eventos de juegos en él. Si los controladores de eventos toman demasiado tiempo, me gustaría poder poner en pausa a ese jugador en particular hasta el próximo evento suspendiendo su hilo.

Al tener un hilo dedicado en el que puedo ejecutar varios controladores de eventos, puedo detener la IA de un jugador en particular en caso de que se interrumpa o demore demasiado.

Respuesta

3

Creo que la mejor solución es usar objetos Task y ponerlos en cola en un StaThreadScheduler ejecutando un único hilo.

Como alternativa, puede usar ActionThread en Nito.Async para crear un hilo normal con una cola incorporada de delegados Action.

Sin embargo, ninguno de estos abordará directamente otra necesidad: la capacidad de "pausar" una acción y continuar con otra. Para hacer esto, necesitaría rociar "puntos de sincronización" a lo largo de cada acción y tener una forma de guardar su estado, volver a ponerlo en cola y continuar con la siguiente acción.

Toda esa complejidad está a punto de acercarse a un sistema de programación de hilos, por lo que recomiendo dar un paso atrás y hacer más de un rediseño. Puede permitir que cada acción se ponga en cola al ThreadPool (recomiendo que cada una sea un objeto Task). Todavía necesitará rociar "puntos de sincronización", pero en lugar de guardar el estado y volver a ponerlos en cola, solo tendrá que pausarlos (bloquearlos).

+0

Gracias por señalar el ActionThread, que parece muy útil. Necesitaba encapsular código externo sobre el cual tengo poco control en un hilo. Todo lo que tengo es delegados al código externo. Si puedo asegurarme de que el objeto está en un hilo en particular, puedo "pausar" ese objeto simplemente suspendiendo el hilo. No creo que el threadpool me permita "pausar" el objeto muy bien. – Raynos

+0

Una palabra de advertencia: es posible (incluso probable) provocar bloqueos accidentales accidentalmente suspendiendo/reanudando subprocesos. Si es posible, cambie el código externo. Si eso no es posible, considere usar prioridades de subprocesos en lugar de suspender/reanudar. –

1

Normalmente, sugeriría usar solo el grupo de subprocesos o la clase BackgroundWorker, pero estos no garantizan que el trabajo se realice en un hilo en particular. No está claro por qué le importa qué hilo ejecuta las obras, pero suponiendo que de alguna manera importa ...

Tendría que pasar el objeto Delegate a través de algún tipo de memoria compartida, como una cola. El hilo de fondo tendría que mirar esta cola, extraer los delegados cuando existan y ejecutarlos.

Si resulta que el grupo de subprocesos es aceptable para ejecutar el código, siempre se puede utilizar el método BeginInvoke del delegado de hacerlo:

// wrap your custom delegate in an action for simplicity ... 
Action someCode =() => yourCustomDelegate(p1, p2, p3, ...); 
// asynchronously execute the currying Action delegate on the threadpool... 
someCode.BeginInvoke(someCode.EndInvoke, action); 
2

Desafortunadamente realmente no hay nada construido para realizar esta acción en cualquier hilo genérico. Puede lograr esto creando una clase que envuelva un subproceso e implemente ISynchonizeInvoke.

Un enfoque simple es crear una cola de procesamiento de eventos en el subproceso dedicado como menciona LBushkin. Sugiero usar una clase Queue<Action> y llamar al delegado de Action directamente. Puede realizar la mayoría de las tareas que necesitaría mediante el uso de acciones delegadas anónimas.

Finalmente, solo como advertencia, sugeriría que utilice un semáforo o EventWaitHandle en lugar de Thread.Sleep en su hilo dedicado. Definitivamente es más amigable que ejecutar tu ciclo de fondo una y otra vez cuando es innecesario.

+0

Gracias, tenía la intención de ejecutar el bucle de fondo una y otra vez. Buscaré en un controlador de espera de evento – Raynos

+1

Estoy de acuerdo con la advertencia sobre 'Thread.Sleep'; sin embargo, el operador debería implementar 'SynchronizationContext' en lugar de' ISynchronizeInvoke' obsoleto. –

0

Para los hilos que crea, solo puede especificar el delegado ThreadStart cuando los crea. No hay ninguna disposición para inyectar un delegado diferente en un hilo creado. El grupo de subprocesos es diferente, ya que le permite enviar delegados a los subprocesos creados anteriormente que se inician en su nombre.

No está claro qué problema está tratando de resolver. ¿Qué intenta lograr (o evitar) al intentar ejecutar múltiples delegados en un hilo?

Cuestiones relacionadas