2013-07-26 14 views
5

Si prega di suggerire quale metodo è corretto (se presente) per un corretto e uso efficiente delle ParallelOptions, TaskCreationOptions e Task.Factory.StartNew (() =>.Uso corretto di ParallelOptions, TaskCreationOptions e Task.Factory.StartNew?

private void NeedToUse_MaxDegreeOfParallelism_Method1() 
{ 
    CancellationTokenSource tokenFor_task = new CancellationTokenSource(); 

    ParallelOptions parOpts = new ParallelOptions(); 
    //parOpts.CancellationToken = tokenFor_task_tpl_Pair01.Token; 
    parOpts.MaxDegreeOfParallelism = Environment.ProcessorCount; 
    //parOpts.TaskScheduler = TaskScheduler.Default; 

    TaskCreationOptions tco = new TaskCreationOptions(); 
    tco = TaskCreationOptions.PreferFairness; 

    Task task = null; 
    task = Task.Factory.StartNew(() => 
    { 
     while (!tokenFor_task.IsCancellationRequested) 
     { 
      LongRunningMethod(); 
     } 
    }, tokenFor_task.Token, tco, TaskScheduler.Default); 
} 


private void NeedToUse_MaxDegreeOfParallelism_Method2() 
{ 
    //CancellationTokenSource tokenFor_task = new CancellationTokenSource(); 

    ParallelOptions parOpts = new ParallelOptions(); 
    parOpts.CancellationToken = tokenFor_task_tpl_Pair01.Token; 
    parOpts.MaxDegreeOfParallelism = Environment.ProcessorCount; 
    parOpts.TaskScheduler = TaskScheduler.Default; 

    TaskCreationOptions tco = new TaskCreationOptions(); 
    tco = TaskCreationOptions.PreferFairness; 

    Task task = null; 
    task = Task.Factory.StartNew(() => 
    { 
     while (!parOpts.CancellationToken.IsCancellationRequested) 
     { 
      LongRunningMethod(); 
     } 
    }, parOpts.CancellationToken, tco, parOpts.TaskScheduler); 
} 

private void NeedToUse_MaxDegreeOfParallelism_Method3() 
{ 
    CancellationTokenSource tokenFor_task = new CancellationTokenSource(); 

    ParallelOptions parOpts = new ParallelOptions(); 
    //parOpts.CancellationToken = tokenFor_task_tpl_Pair01.Token; 
    parOpts.MaxDegreeOfParallelism = Environment.ProcessorCount; 
    //parOpts.TaskScheduler = TaskScheduler.Default; 

    TaskCreationOptions tco = new TaskCreationOptions(); 
    tco = TaskCreationOptions.PreferFairness; 

    Task task = null; 
    task = Task.Factory.StartNew(() => 
    { 
     Parallel.Invoke(parOpts,() => 
     //while is already in LongRunningMethod() because can not be here 
     //while (!tokenFor_task.IsCancellationRequested) 
     //{ 
      LongRunningMethod() 
     //} 
     ); 
    }, tokenFor_task.Token, tco, TaskScheduler.Default); 
} 

private void NeedToUse_MaxDegreeOfParallelism_Method4() 
{ 
    CancellationTokenSource tokenFor_task = new CancellationTokenSource(); 

    ParallelOptions parOpts = new ParallelOptions(); 
    //parOpts.CancellationToken = tokenFor_task_tpl_Pair01.Token; 
    parOpts.MaxDegreeOfParallelism = Environment.ProcessorCount; 
    //parOpts.TaskScheduler = TaskScheduler.Default; 

    TaskCreationOptions tco = new TaskCreationOptions(); 
    tco = TaskCreationOptions.PreferFairness; 

    Task task = null; 
    Parallel.Invoke(parOpts,() => 
     task = Task.Factory.StartNew(() => 
     { 
      while (!tokenFor_task.IsCancellationRequested) 
      { 
       LongRunningMethod(); 
      } 
     }, tokenFor_task.Token, tco, TaskScheduler.Default) 
    ); 
} 

Attualmente non ottengo errori Il primo e il secondo metodo non tengono conto di MaxDegreeOfParallelism che ho bisogno di utilizzare. Idealmente non userò Parallel.Invoke ma come includere parOpts.MaxDegreeOfParallelism in Task.Factory.StartNew?

risposta

7

Il tuo codice e domanda non ha molto senso: Task.Factory.StartNew() non accetta MaxDegreeOfParallelism, perché esegue un singola azione. Parallel.Invoke() accetta tale parametro, ma non ha senso utilizzare quel metodo quando si ha una singola azione.

Invece di fare una domanda molto specifica come questa, penso che dovresti fare un passo indietro, guardare cosa stai effettivamente cercando di ottenere e quindi eventualmente fare una nuova domanda al riguardo.

EDIT: Ora penso di aver finalmente capito cosa stai cercando di fare: su ogni core, vuoi eseguire un ciclo separato. Per fare questo, si potrebbe ad esempio utilizzare Parallel.For():

Parallel.For(0, Environment.ProcessorCount, parOpts,() => 
    { 
     while (!tokenFor_task.IsCancellationRequested) 
     { 
      LongRunningMethod(); 
     } 
    }); 
+0

ho bisogno LongRunningMethod() per essere eseguito in parallelo su tutti i core, quando possibile. – as74