Domanda

Secondo la documentazione, Waithandle in .NET dovrebbe essere disposto esplicitamente / implicitamente.Tuttavia, sto avendo problemi a raggiungere questo obiettivo per la seguente attività di sincronizzazione di base:

    .
  • Un'attività che richiede tempo viene eseguita su un filo.
  • Il thread principale attende il compito di completare per un periodo di tempo predefinito.Il filo principale deve procedere se a.L'attività è completata o b.il timeout si è verificato.

Qui il mio tentativo di utilizzare un oggetto autoresetevent:

using(var waitHandle = new AutoResetEvent(false)){
    var worker = new Thread(() =>
    {
        try
        {
            TimeConsumingTask();
            waitHandle.Set(); //throws System.ObjectDisposedException: Safe handle has been closed
        }
        catch (Exception e)
        {...}
    }) {IsBackground = true};
    worker.Start(); //start worker

    const int waitTimeInMs = 5000; 
    var signaled = waitHandle.WaitOne(waitTimeInMs);//block main thread here. 
    if (!signaled)
    { //if timed out
       worker.Interrupt();
    }
}
.

Esiste un'ovvia condizione di razza in cui il thread principale attende gli orari di attesa e dispone dell'oggetto dell'impugnatura di attesa che causa un'eccezione ObjectDiseconException.C'è qualche altro modo in cui l'ho impostato in modo che la maniglia sia disposta correttamente e senza causare l'eccezione?

È stato utile?

Soluzione

Certo, non c'è un modo decente per farlo. Nota avanti davanti che hai dipinto te stesso in quell'angolo lasciando essenzialmente un filo che scorreva selvaggio, niente particolarmente carino a riguardo.

Ma ti stai concentrando sul problema molto più piccolo. La classe del filo stesso è già un maiale risorse, consumando un megabyte di VM e cinque oggetti di sincronizzazione. Ma non ha disposto () metodo. Questo è stato un design coraggioso, non c'è solo un modo decente di chiamare il metodo.

Smaltimento è opzionale , nulla che drammatico accada quando non lo chiami. La classe ha la schiena, ha un finalizzatore che garantisce che la risorsa del sistema operativo nativo venga rilasciato. Quale funzionerà, alla fine, non solo il più velocemente quanto desideri.

Confronta questo a una classe con un design meno coraggioso, la classe Task ha un metodo di disposizione (). Che, come il filo, è quasi difficile da chiamare. The Guida da Gurus .NET è a Non preoccuparti.

lo stesso qui.

Altri suggerimenti

Il waithandle è lo smaltimento perché l'uso dell'utilizzo richiama un nuovo thread un restituisce immediatamente, facendo sì che il waithandle venga smaltito.

Cosa dovresti fare è esplicitamente la chiamata smaltire dopo aver completato il tuo lavoro anziché la tua istruzione usando:

waitHandle.WaitOne(waitTimeInMs);
if (!signaled)
{ //if timed out
   worker.Interrupt();
}
waitHandle.Dispose();
.

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