Middle+
Kas on võimalik kutsuda asünkroonset koodi sünkroonselt?
sobes.tech AI
Vastus AI-lt
jah, see on võimalik, kuid see võib põhjustada probleeme, eriti deadlock'e.
Meetodid asünkroonse koodi sünkroonselt kutsumiseks:
-
Kasutades
Resultomadust võiWait()meetoditTaskobjektil:// Asünkroonse meetodi sünkroonselt kutsumine Task.Run(async () => await SomeAsyncTask()).Wait(); // Asünkroonse meetodi tulemuse saamine sünkroonselt var result = SomeAsyncTaskWithResult().Result;async Task SomeAsyncTask() { await Task.Delay(100); } async Task<int> SomeAsyncTaskWithResult() { await Task.Delay(100); return 42; } -
Kasutades
GetAwaiter().GetResult():// Asünkroonse meetodi sünkroonselt kutsumine tulemusega var result = SomeAsyncTaskWithResult().GetAwaiter().GetResult();
Negatiivsed aspektid:
- Deadlock'id: Kõige levinum probleem, eriti UI- või ASP.NET kontekstides, kus
Wait()jaResultblokeerivad jooksva niidi, oodates ülesande lõpetamist. Kui asünkroonne meetod püüab haarata blokeeritud sünkroniseerimiskonteksti jätkamiseks pärastawait, tekib deadlock. - Jõudluse ja skaleeritavuse halvenemine: Niitide blokeerimine asünkroonsete operatsioonide asemel tarbib rohkem ressursse ja vähendab rakenduse võimet töödelda palju samaaegseid päringuid (näiteks veebirakendustes).
- Mõistmata käitumine: Asünkroonse ja sünkroonse koodi segamine võib muuta programmi täitmise voogu keerulisemaks mõistmiseks ja silumiseks.
Enamikel juhtudel on õige lähenemine await kasutamine asünkroonse täitmise jätkamiseks või, kui on vaja täita asünkroonset koodi rakenduse sisenemispunktis (näiteks Main), kasutada Task.Run() koos Wait()-ga või muuta Main asünkroonseks, kui C# versioon seda toetab (async Task Main).
Turvaline näide:
// Turvaline asünkroonse meetodi kutsumine sünkronilisest kontekstist
Task.Run(async () =>
{
await SomeAsyncTask();
}).Wait();
// Turvaline asünkroonse meetodi kutsumine tulemusega
var result = Task.Run(async () =>
{
return await SomeAsyncTaskWithResult();
}).Result;