2011-11-07 18 views
13

Da quello che posso dire, ho delle informazioni fuorvianti. Ho bisogno di avere un thread separato in esecuzione in background.Come garantire che venga creato un nuovo thread quando si utilizza il metodo Task.StartNew

Al momento lo faccio in questo modo:

var task = Task.Factory.StartNew 
     (CheckFiles 
      , cancelCheckFile.Token 
      , TaskCreationOptions.LongRunning 
      , TaskScheduler.Default);//Check for files on another thread 

private void CheckFiles() 
{ 
    while (!cancelCheckFile.Token.IsCancellationRequested) 
    { 
     //do stuff 
    } 
} 

Questo crea sempre un nuovo thread per me. Tuttavia, dopo diverse discussioni, anche se è contrassegnato come LongRunning non garantisce che verrà creato un nuovo thread.

In passato ho fatto qualcosa di simile:

thQueueChecker = new Thread(new ThreadStart(CheckQueue)); 
thQueueChecker.IsBackground = true; 
thQueueChecker.Name = "CheckQueues" + DateTime.Now.Ticks.ToString(); 
thQueueChecker.Start(); 


private void CheckQueue() 
{ 
    while (!ProgramEnding) 
    { 
      //do stuff 
    } 
} 

Consiglieresti che torno a questo approccio per garantire un nuovo thread viene utilizzato?

+0

'LongRunning' è solo un suggerimento per lo scheduler - se devi assolutamente avere sempre un nuovo Thread, dovrai crearne uno. –

+0

Fancy aggiungendo che come risposta? – Jon

+0

Grazie Jon :) –

risposta

5

LongRunning è solo un suggerimento per lo scheduler - se devi assolutamente avere sempre un nuovo Thread, dovrai crearne uno.

+1

Penso che questa sia la risposta corretta. Mi piace l'astrazione dei thread usando Task ma nessuno può garantire un nuovo thread. Henk dice che dovrei lasciarlo fare quello che voglio, ma questo non garantisce una nuova discussione. – Jon

+0

Pensi che i commenti di Henk che suggeriscono che io sia sulla strada sbagliata siano validi e se così mi piacerebbe sapere/imparare di più – Jon

+0

Penso che la confusione riguardi parole come "garanzia". L'opzione 'LongRunning' non è" garantita "per fare qualsiasi cosa. Tuttavia, il TaskScheduler predefinito in .NET 4 crea un nuovo thread e * è improbabile * che cambi. L'utilizzo di Google Task è un'astrazione che semplifica il codice, ma si perde il controllo. Se è davvero importante per te, puoi sempre scrivere un TaskScheduler che garantisce una nuova discussione e avere il meglio di entrambi i mondi :) –

3

È necessario specificare perché "" è sempre necessario un thread separato ".

void Main() 
{ 
    var task = Task.Factory.StartNew(CheckFiles, 
    cancelCheckFile.Token, 
    TaskCreationOptions.LongRunning, 
    TaskScheduler.Default); 

    task.Wait(); 
} 

Uno scheduler intelligente utilizzerà 1 thread qui. Perché non dovrebbe?


ma generalmente CheckFiles() metodo verrà eseguito su un'altra (quella chiamata) thread. Il problema è se quel thread è stato creato appositamente o se potrebbe anche essere eseguito su più thread (in successione).

Quando si utilizzano Attività, si rinuncia al controllo sulla Discussione. E quella dovrebbe essere una buona cosa.

+0

Voglio un thread separato per scrivere su file su un altro thread in modo che il thread chiamante sia lasciato a fare ciò che vuole. Potrei volere che un altro thread elabori i dati ricevuti da un socket. In entrambe queste circostanze i dati verranno aggiunti a una coda e poi rimossi dalla coda su un altro thread lasciando il thread chiamante libero di fare altre cose – Jon

+0

Quindi lo scheduler farà esattamente quello che ti serve se lo permetti. –

+0

Ma come posso garantirlo. Come sai che lo scheduler lo farà per me su un altro thread? L'altra cosa che non ho specificato e che tu fai è compito. Aspetta. Come lo voglio su un altro thread non mi aspetto() – Jon

15

Il pianificatore di attività predefinito ThreadPoolTaskScheduler crea sempre un nuovo thread per attività a esecuzione prolungata. Non usa il pool di thread come puoi vedere. Non è diverso come l'approccio manuale per creare il thread da soli. In teoria, potrebbe accadere che lo scheduler di .NET 4.5 faccia qualcosa di diverso, ma in pratica è improbabile che cambi.

protected internal override void QueueTask(Task task) 
{  
    if ((task.Options & TaskCreationOptions.LongRunning) != TaskCreationOptions.None) 
    { 
    new Thread(s_longRunningThreadWork) { IsBackground = true }.Start(task); 
    } 
    else 
    { 
    bool forceGlobal = 
     (task.Options & TaskCreationOptions.PreferFairness) != TaskCreationOptions.None; 
    ThreadPool.UnsafeQueueCustomWorkItem(task, forceGlobal); 
    } 
} 
+3

Non riesco a vedere cosa c'è di sbagliato nella mia risposta. Potresti elaborare il tuo ragionamento per il downvote? –

+3

@Ramhound Mi rendo conto che questo è antico, ma xp! = Risposta corretta. Alois è corretto, vedi il codice sorgente .NET Framework per 'ThreadPoolTaskScheduler' - secondo metodo giù' QueueTask': referencesource.microsoft.com/#mscorlib/system/threading/Tasks/ThreadPoolTaskScheduler.cs C'è anche un commento nel codice: // Esegui attività LongRunning sul thread dedicato. –

8

Dipende dallo Scheduler che si utilizza. Esistono due implementazioni di magazzino, ThreadPoolTaskScheduler e SynchronizationContextTaskScheduler. Quest'ultimo non inizia affatto un thread, utilizzato dal metodo FromCurrentSynchronizationContext().

Il ThreadPoolTaskScheduler è quello che ottieni. Che in effetti utilizza l'opzione LongRunning, userà un Thread normale se impostato. Importante per evitare di morire di fame altri thread TP. Otterrai una discussione TP senza l'opzione. Questi sono dettagli di implementazione soggetti a modifiche senza preavviso, anche se lo considererei improbabile in qualunque momento presto.

+0

Perché non riesco a trovare alcun risultato (articolo MSDN online) dopo aver cercato dal sito 'ThreadPoolTaskScheduler: msdn.microsoft.com -site: social.msdn.microsoft.com' o dal sito' SynchronizationContextTaskScheduler: msdn.microsoft.com -site: social .msdn.microsoft.com'? –

+1

Perché sono classi interne. Come ho detto, "dettagli di implementazione". –

+0

Grazie. Posso chiedere cosa sono le "implementazioni di magazzino"? –

Problemi correlati