Domanda

Prima che la gente suggeriscono che: Non sono usando Thread.sleep per niente , tranne cercando di trovare un modo di lavorare intorno ad esso. Sto cercando di gestire il codice futuro di altre persone che potrebbero non essere .sleep () libera. Ho una buona conoscenza di quanto è orribile per sincronizzare le cose.

I accettare un filo in un pezzo del mio codice. Voglio essere in grado di impostare un limite a vita di questo thread. Il mio solito metodo di farlo va in questo modo:

Thread outer = new Thread(() =>
{
    externalThread.Start();
    externalThread.Join();
});
outer.Start();
outer.Join(lifetime);
if (outer.ThreadState != ThreadState.Stopped)
{
    outer.Abort();
}
inner.Join();

Da allora ho scoperto che a quanto pare non riesco a svegliarmi un filo di dormire prima del termine del sonno. A peggiorare le cose, questo scrive ancora la console se dò una vita di 10 millisecondi:

new Thread(() => { Thread.Sleep(2000); Console.WriteLine("second"); })

Sebbene realizzo .Abort () non è un hard-limite esecuzione thread. Sembra 2 secondi sarebbero abbastanza di un avvertimento, ma io non credo ...

Ho provato il controllo per lo stato WaitSleepJoin, e .Interrupt (); si blocca il filo, o genera un'eccezione (mi dispiace, non sapendo che. Windows me si è schiantato se alcun debugger di esecuzione dice, e se è in esecuzione viene eseguito come se interrupt non è stato chiamato), e ancora scrive alla console dopo 2 secondi . .Resume () apparentemente non fa nulla per un filo di sonno.

è C'è un modo per riattivare un filo, senza attendere la sua sospensione per scadere? Capisco che l'arresto non è "immediato", in modo che Console.WriteLine può essere chiamato a prescindere; è il 2 secondi di attesa che mi rode. Che cosa succede se si tratta di un 10 giorni di attesa? Dal momento che non riesco a controllare i fili che vengono in, non ho modo di saperlo, e sembra non c'è modo di prevenzione una cosa del genere ...

È stato utile?

Soluzione

Non v'è alcun modo svegliarsi un filo da un sonno. Si può solo interrompere una discussione chiamando Abort o Interrupt (entrambi i quali gettare un ThreadAbortException).

Ma per l'indirizzo si domanda del perché durante l'esecuzione:

new Thread(() => { Thread.Sleep(2000); Console.WriteLine("second"); })

10ms con un timeout ancora stampe, è perché il codice per il controllo del tempo di vita filo non fa quello che si vuole fare.

Quindi hai externalThread ed esteriore. Si inizia esterno (che inizia un nuovo thread, consente di chiamare filo 1) e dall'inizio chiamata esterna sulla filettatura esterna (che inizia un nuovo thread, consente di chiamare filo 2). Quindi, avete appena iniziato due nuove discussioni.

Quando si chiama outer.About(), che Aborts unico filo 1. Il filo iniziato chiamando externalThread.Start(), filo 2 continua l'esecuzione fino al completamento dal momento che nulla interrompe esso.

Non sono sicuro di quello che il vostro stanno cercando di realizzare con la filettatura esterna supplementare. Non sarebbe più semplice:

externalThread.Start();
externalThread.Join(lifetime);
if (externalThread.ThreadState != ThreadState.Stopped)
{
    externalThread.Abort();
}

Altri suggerimenti

Usa WaitOne timer per le discussioni di controllo di origine sconosciuta +.

o se si desidera avere il controllo sul codice di lavoratore del thread:

modo un po hacky, per ottenere di più "sleep reattivo" quando non gradire i timer / altri thread utilizzati per svegliare il filo verso l'alto

utilizzarlo al posto di Thread.Sleep normale

    private void WaitFor(int milis)
    {
        const int interval = 500;

        if (milis <= interval)
        {
            throw new ArgumentException();
        }

        var sections = milis / interval;
        for (var s = 0; s < sections && (!ShouldQuit); ++s)
        {
            Thread.Sleep(interval);
        }
    }

notare la bandiera ShouldQuit, essendo un campo di classe accessibile da entrambi i fili

Naturalmente questo ha caratteristiche cpu-utilizzo peggiori / wait basato timer evento

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