È ok attendere lo stesso compito da più thread – è in attesa di thread sicuro?

È in attesa di thread sicuro? Sembra che la class Task sia thread-safe, quindi credo che l’attesa sia anche sicura, ma non ho trovato nessuna conferma da nessuna parte. Inoltre, la sicurezza del thread è un requisito per i camerieri personalizzati – intendo per i metodi IsCompleted, GetAwaiter, ecc.? Cioè se quei metodi non sono thread sicuro, attenderanno essere thread sicuro? Tuttavia, non mi aspetto di avere bisogno di un cameriere personalizzato in qualsiasi momento presto.

Un esempio di scenario utente: diciamo che ho un’attività in background che restituisce un risultato in modo asincrono, che viene quindi utilizzato da più thread:

using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace scratch1 { class Foo { Task _task; public Foo() { _task = Task.Run(async () => { await Task.Delay(5000); return 5; }); } // Called from multiple threads public async Task Bar(int i) { return (await _task) + i; } } class Program { public static void Main(string[] args) { Foo foo = new Foo(); List tasks = new List(); foreach (var i in Enumerable.Range(0, 100)) { tasks.Add(Task.Run(async () => { Console.WriteLine(await foo.Bar(i)); })); } Task.WaitAll(tasks.ToArray()); } } } 

Come hai accennato, l’ await è abbastanza sottile da non vedere i fili in primo luogo.

Il codice associato await (il codice generato dal compilatore all’interno della macchina a stati e le classi di supporto nel BCL) funzionerà sempre su un solo thread alla volta. (può passare a un thread diverso quando ritorna dall’attesa, ma la corsa precedente sarà già terminata)

L’effettiva sicurezza del thread dipende dall’object che stai aspettando.
Deve avere un modo thread-safe per aggiungere i callback (o await due volte in una volta potrebbe interrompersi).

Inoltre, deve chiamare la richiamata esattamente una volta oppure può rompere la macchina a stati. (in particolare, se esegue la sua richiamata su due thread contemporaneamente, le cose andranno terribilmente male)

Task è thread-safe.