Ho il seguente codice sincrono:Conversione ciclo per compiti
foreach (var step in result) {
step.Run();
}
ho cercato di convertirlo in compiti, ma non sono riuscito a farlo. Ho provato a convertirlo utilizzando Task.WhenAll
come questo (e l'ho fatto aggiungere asincrona per la firma del metodo):
var tasks = new List<Task>();
foreach (var step in result) {
tasks.Add(new Task(() => step.Run()));
}
await Task.WhenAll(tasks);
Questo restituisce immediatamente e non esegue il metodo Run()
. Quindi ho provato a convertirlo al seguente codice:
var tasks = new List<Task>();
foreach (var step in result) {
tasks.Add(new Task(() => step.Run()));
}
var task = Task.WhenAll(tasks);
task.Wait();
Questo blocco per sempre. Tuttavia, quando creo un all'interno del ciclo funziona:
foreach (var step in result) {
var t = Task.Run(() => step.Run());
t.Wait();
}
Se uso invece await Task.Run(() => step.Run());
attende solo la prima e riprende il filo conduttore.
Il percorso è simile al seguente:
public async void Run() {
var result = Work();
if (null != result && result.Count > 0) {
var tasks = new List<Task>();
foreach (var step in result) {
await Task.Run(() => step.Run());
}
}
}
Tutte le fasi di implementare un metodo di lavoro() (che è astratto in una classe base). Il mio primo passo è simile al seguente:
class NoWorkStep : WorkerStep {
protected override IList<WorkerStep> Work() {
Console.WriteLine("HERE");
List<WorkerStep> newList = new List<WorkerStep>();
for (int i = 0; i < 10; i++) {
newList.Add(new NoWorkStep2());
}
return newList;
}
}
E il mio secondo passo è simile al seguente:
class NoWorkStep2 : WorkerStep {
protected override IList<WorkerStep> Work() {
Console.WriteLine("HERE-2");
return new List<WorkerStep>();
}
}
ho semplice creare un'istanza di NoWorkStep e chiamare instance.Run()
.
Dove si verifica un problema con l'esecuzione dei passaggi con Task.WhenAll
?
Edit: Calling codice dopo ho cambiato il metodo Run per async Task RunAsync
:
private static async void doIt() {
var step = new NoWorkStep();
await step.RunAsync();
}
async _void_ Run()? – Ewan
Non utilizzare 'new Task'. Il motivo per cui il tuo quarto esempio funziona non è perché "Wait" è all'interno del ciclo - funziona perché stai usando "Task.Run" invece di "new Task". – Luaan