Domanda

sto usando un AutoResetEvent in cui più chiamate Set possono essere effettuate su un evento (Gestione delle eccezioni). Ci sono momenti in cui un ulteriore set viene chiamato, in tal modo, quando il codice effettua una seconda chiamata su un evento WaitOne, passa appena a destra attraverso la porta, perché è già stato aperto.

La soluzione è quella di chiamare reset destra prima del WaitOne. C'è una soluzione detergente o è questo l'unico modo per farlo? Esempio di codice:

private void DoSomeWork()
{
    Thread thrd = new Thread(new ThreadStart(DoSomeOtherStuff));
    thrd.Start();

    //mEvt.Reset();
    mEvt.WaitOne();

    //continue with other stuff
}

private void DoSomeOtherStuff()
{
    /* lots of stuff */

    mEvt.Set();
}

private void ExceptionTriggerNeedsToBreakOutOfDoSomeWork()
{
   mEvt.Set();
}

Dopo l'eccezione viene gestita, ho bisogno di chiamare di nuovo DoSomeWork, ma dal momento Set potrebbe essere stato chiamato in molteplici eccezioni (o eccezioni rilanciati), il WaitOne scorre solo attraverso.

La mia soluzione è quella di chiamare sempre reset prima del WaitOne. È questa la soluzione approriate, cattiva progettazione, o c'è un diverso tipo di evento che gestirà questo scenario?

EDIT:. Ho appena trasferita Reset commentato (soluzione proposta) accanto all'evento

È stato utile?

Soluzione

La mia preoccupazione è che se si chiama Reset () prima WaitOne (), sei nei guai se non Set () viene mai chiamato. Questo potrebbe accadere se si chiama Set (), poi ha colpito Reset () subito dopo, prima di colpire WaitOne (). Anche se si sta chiamando Set () due volte, non c'è alcuna garanzia che non chiamerà Reset () dopo che entrambi, bloccando il filo con alcun meccanismo per il rilascio.

Idealmente, si avrebbe un try..catch..istruzione bloccare, e chiamare il Set () nel blocco finally, e non avere la vostra diffusione gestione delle eccezioni attraverso metodi. Fa il lavoro per voi?

Hans è corretto che in questo scenario, il multithreading è inutile. Le mie preoccupazioni si applicano solo se si è veramente multithreading con le chiamate a WaitOne ().

E 'riguarda anche me che si sta chiamando insieme più di una volta ... vuol dire che quando la prima serie si chiama, la risorsa in realtà dovrebbe rimanere bloccato? Se siete ancora in grado di colpire Set () una seconda volta, a me che dice che sei ancora l'esecuzione di codice che funziona con risorse condivise. Nel qual caso non si vuole la chiamata a WaitOne () per sbloccare.

Da notare anche, da MSDN:

  

Non v'è alcuna garanzia che ogni chiamata al metodo Set rilascerà un filo. Se due chiamate sono troppo vicini tra loro, in modo tale che si verifica la seconda chiamata prima che un thread è stato rilasciato, solo un thread viene rilasciato. E 'come se la seconda chiamata non è accaduto.

In ogni caso, sembra che il codice dovrebbe andare sia il percorso di un'eccezione, o in esecuzione di completamento, ma non entrambi. OSSIA non si dovrebbe essere chiamata Set () due volte.

Altri suggerimenti

Questo non è un vero problema, il WaitOne () chiamare automaticamente ripristina l'evento. Dopo tutto, è stato utilizzato un AutoResetEvent, non un ManualResetEvent. frase chiave qui è Ripristino automatico.

Vedendo che la cottura a vapore a destra attraverso la chiamata WaitOne () è abbastanza normale anche. Hai un bel core CPU multiple, il filo è cominciato subito quando hai chiamato Start () e non ha preso, ma pochi microsecondi per ottenere il lavoro fatto. Millisecondi, qualunque sia, più veloce di un batter d'occhio.

Forse più al punto, è solo che non hanno bisogno di un thread qui. A partire uno, quindi in attesa che finisca è inutile. Basta chiamare il DoSomeOtherStuff () direttamente.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top