Middle+
Կարո՞ղ է սինխրոն կերպով կանչել ասինխրոնային կոդը։
sobes.tech AI
Պատասխան AI-ից
այո, կարելի է, բայց դա կարող է հանգեցնել խնդիրների, մասնավորապես deadlock-ների:
Ասինխրոնային կոդը սինխրոնային կերպով կանչելու եղանակներ:
-
Օգտագործել
Resultհատկությունը կամWait()մեթոդըTaskօբյեկտի վրա:// Ասինխրոնային մեթոդի սինխրոնային կանչում Task.Run(async () => await SomeAsyncTask()).Wait(); // Ասինխրոնային մեթոդի արդյունքը ստանալ սինխրոնային կերպով var result = SomeAsyncTaskWithResult().Result;async Task SomeAsyncTask() { await Task.Delay(100); } async Task<int> SomeAsyncTaskWithResult() { await Task.Delay(100); return 42; } -
Օգտագործել
GetAwaiter().GetResult():// Ասինխրոնային մեթոդը սինխրոնային կերպով կանչել և արդյունքը ստանալ var result = SomeAsyncTaskWithResult().GetAwaiter().GetResult();
Դեֆիցիտներ այս մոտեցման:
- Deadlock-ներ: Ամենատարածված խնդիր, հատկապես UI-թերթերում կամ ASP.NET կոնտեքստերում, որտեղ
Wait()ևResultբլոկավորում են ընթացիկ թերթը, սպասելով առաջադրանքի ավարտին: Եթե ասինխրոնային մեթոդը փորձում է բռնել բլոկավորված սինխրոնացման կոնտեքստըawait-ից հետո շարունակելու համար, դա հանգեցնում է deadlock-ի: - Աշխատունակության և մասշտաբայնության վատթարացում: Թերթերի բլոկավորումը փոխարենը օգտագործելիս ասինխրոնային օպերացիաները, այն ավելի շատ ռեսուրսներ է սպառում և նվազեցնում է հավելվածի կարողությունը միաժամանակ բազմաթիվ հարցումների մշակման համար:
- Անբացատրելի վարքագիծ: Ասինխրոնային և սինխրոնային կոդի խառը օգտագործումը կարող է դարձնել ծրագրի կատարման հոսքը բարդ և դժվարին հասկանալու և թեստավորման համար:
Ամեն դեպքում, ճիշտ մոտեցումը await-ն օգտագործելն է ասինխրոնային կատարմանը շարունակելու համար կամ, եթե անհրաժեշտ է կատարել ասինխրոնային կոդ ծրագրի մուտքի կետում (օրինակ, Main), օգտագործել Task.Run()-ը Wait()-ի հետ կամ դարձնել Main-ը ասինխրոնային, եթե C# տարբերակը դա աջակցում է (async Task Main):
Օրինակ՝ անվտանգ կանչելիս ասինխրոնային կոդը սինխրոնային մեթոդից, օգտագործելով Task.Run-ը՝
// Անվտանգ կանչ սինխրոնային կոնտեքստից
Task.Run(async () =>
{
await SomeAsyncTask();
}).Wait();
// Անվտանգ կանչ արդյունքով
var result = Task.Run(async () =>
{
return await SomeAsyncTaskWithResult();
}).Result;