2011-06-10 22 views
6

Tengo una función que debe ejecutarse solo cuando se recibe una devolución de llamada de la función asincrónica.Cómo suspender un hilo hasta que se reciba la devolución de llamada para la función asíncrona?

Como

me llaman función asíncrona Stop() y poco después de que yo llamo la función asíncrona Start().

El problema antes de que se detenga la Devolución de llamada se llama Start() y, por lo tanto, tengo problemas. También no puedo separar la convocatoria de dos funciones Como si yo no puedo hacer esto .:

public void SomeFunction() 
{ 
    Stop(); 
} 

public void Stop_CallBack(eventargs e) 
{ 
    Start(); 
} 

que tengo que hacer esto: la función

public void SomeFunction() 
{ 

    Stop(); 
    //Do something; 

    Start(); 
} 

pero antes de recibir llamada de la parada de vuelta mi inicio() se ejecuta creando así los problemas para mí.

¿Alguien me puede ayudar cómo puedo solucionar este problema.

Respuesta

18

Esto es cuando desea utilizar los controles de espera. Aquí está un ejemplo de código corto para mostrar uno de los enfoques:

class AsyncDemo 
{ 
    AutoResetEvent stopWaitHandle = new AutoResetEvent(false); 
    public void SomeFunction() 
    {  
     Stop(); 
     stopWaitHandle.WaitOne(); // wait for callback  
     Start(); 
    } 
    private void Start() 
    { 
     // do something 
    } 
    private void Stop() 
    { 
     // This task simulates an asynchronous call that will invoke 
     // Stop_Callback upon completion. In real code you will probably 
     // have something like this instead: 
     // 
     //  someObject.DoSomethingAsync("input", Stop_Callback); 
     // 
     new Task(() => 
      { 
       Thread.Sleep(500); 
       Stop_Callback(); // invoke the callback 
      }).Start(); 
    } 

    private void Stop_Callback() 
    { 
     // signal the wait handle 
     stopWaitHandle.Set(); 
    } 

} 
+1

¿Puedes explicar por qué necesitas 'Stop_Callback'? ¿Por qué no llamar 'stopWaitHandle.Set();' directamente a la tarea? –

+1

@Daniel: * I * no lo necesito; pero la pregunta indica * "[...] función que debe ejecutarse solo cuando se recibe una devolución de llamada [...]" * y el OP ya había sugerido dicha devolución de llamada en la muestra de código dada. Tiendo a querer reestructurar el código OP lo menos posible. Podría ser que la devolución de llamada se invoque desde un código de terceros que no tenga acceso al identificador de espera, por ejemplo. –

+0

No puedo llamar a Stop_callback. Esta es la devolución de llamada que recibo de alguna otra aplicación. – Sumit

2

Puesto que éstos se parecen a las funciones miembro, puede agregar una variable miembro de evento (ya sea un ManualResetEvent o un AutoResetEvent. Luego, en el método Stop() que establezca el evento para señalizado. En medio de las llamadas para Detener() y start() espere a que el evento

private AutoResetEvent _stopped = new AutoResetEvent(false); 

public void SomeFunction() 
{ 
    Stop(); 
    _stopped.WaitOne(); 
    Start(); 
} 

En la función de parada que haría

private void Stop() 
{ 
    try 
    { 
     // Your code that does something to stop 
    } 
    finally 
    { 
     _stopped.Set(); // This signals the event 
    } 
} 

Si se utiliza un ManualResetEvent -.

private ManualResetEvent _stopped = new ManualResetEvent(false); 

public void SomeFunction() 
{ 
    Stop(); 
    _stopped.WaitOne(); 
    Start(); 
} 

private void Stop() 
{ 
    try 
    { 
     // Your code that does something to stop 
    } 
    finally 
    { 
     _stopped.Set(); // This signals the event 
    } 
} 

private void Start() 
{ 
    _stopped.Reset(); 

    // Your other start code here 
} 
+0

Ya he probado con AutoResetEvent y ManualRestEvent y que aún no ha trabajado – Sumit

+0

Si utilizar un ManualResetEvent entonces usted tiene que restablecerla ('_stopped.Reset()') después de la llamada de WaitOne, de lo contrario permanece en un estado señalado. – pstrjds

+0

¿A qué te refieres con que no funcionó con los eventos de reinicio automático y manual? ¿Tu código no se bloqueó en la llamada a WaitOne()? En ese caso, ¿podría publicar más código? Si tiene una función que está llamando a Stop, haciendo algo y luego llamando a Start. Siempre que el evento se señale en el Stop y solo se reinicie en el inicio, su código se bloqueará en WaitOne hasta que se marque el evento. – pstrjds

Cuestiones relacionadas