'අසින්ක්' සහ 'බලා සිටින්න' භාවිතා කරන්නේ කෙසේද සහ කවදාද?


1089

මගේ අවබෝධයෙන් කළ යුතු asyncහා කළawait යුතු එක් ප්‍රධාන දෙයක් වන්නේ කේතය ලිවීමට සහ කියවීමට පහසු කරවීමයි - නමුත් ඒවා දිගු කාලීන තර්කනය සිදු කිරීම සඳහා පසුබිම් නූල් බිහි කිරීමට සමානද?

මම දැනට වඩාත් මූලික උදාහරණය අත්හදා බලමි. මම පේළි කිහිපයක් පේළිගත කර ඇත. ඔබට එය මා වෙනුවෙන් පැහැදිලි කළ හැකිද?

// I don't understand why this method must be marked as `async`.
private async void button1_Click(object sender, EventArgs e)
{
    Task<int> access = DoSomethingAsync();
    // task independent stuff here

    // this line is reached after the 5 seconds sleep from 
    // DoSomethingAsync() method. Shouldn't it be reached immediately? 
    int a = 1; 

    // from my understanding the waiting should be done here.
    int x = await access; 
}

async Task<int> DoSomethingAsync()
{
    // is this executed on a background thread?
    System.Threading.Thread.Sleep(5000);
    return 1;
}

54
ඉහත උදාහරණ කේතය සම්පාදනය කිරීමේදී ඔබට අනතුරු ඇඟවීමක් ලැබෙන බව ඔබේ උදාහරණයේ සටහන් කරන්න. අනතුරු ඇඟවීම කෙරෙහි අවධානය යොමු කරන්න . මෙම කේතය තේරුමක් නැති බව එය ඔබට කියයි.
එරික් ලිපර්ට්

Answers:


771

භාවිතා කරන විට asyncසහawait සම්පාදකයා පසුබිමේ රාජ්‍ය යන්ත්‍රයක් ජනනය කරයි.

සිදුවෙමින් පවතින ඉහළ මට්ටමේ විස්තර කිහිපයක් මට පැහැදිලි කළ හැකි යැයි මම බලාපොරොත්තු වන උදාහරණයක් මෙන්න:

public async Task MyMethodAsync()
{
    Task<int> longRunningTask = LongRunningOperationAsync();
    // independent work which doesn't need the result of LongRunningOperationAsync can be done here

    //and now we call await on the task 
    int result = await longRunningTask;
    //use the result 
    Console.WriteLine(result);
}

public async Task<int> LongRunningOperationAsync() // assume we return an int from this long running operation 
{
    await Task.Delay(1000); // 1 second delay
    return 1;
}

හරි, ඉතින් මෙතන මොකද වෙන්නේ:

  1. Task<int> longRunningTask = LongRunningOperationAsync(); ක්‍රියාත්මක කිරීමට පටන් ගනී LongRunningOperation

  2. ස්වාධීන වැඩ කටයුතු සිදු කරනුයේ ප්‍රධාන නූල් (නූල් හැඳුනුම්පත = 1) යැයි උපකල්පනය කරමු await longRunningTask .

    දැන්, longRunningTaskඑය අවසන් වී නොමැති අතර එය තවමත් ක්‍රියාත්මක වන්නේ නම්, MyMethodAsync()එහි ඇමතුම් ක්‍රමයට නැවත පැමිණෙනු ඇත, එබැවින් ප්‍රධාන නූල් අවහිර නොවේ. longRunningTaskඑය සිදු කළ විට ThreadPool වෙතින් නූල් (ඕනෑම නූල් විය හැකිය) MyMethodAsync()එහි පෙර සන්දර්භය වෙත නැවත ක්‍රියාත්මක වන අතර (මෙම අවස්ථාවේදී ප්‍රති result ලය කොන්සෝලය වෙත මුද්‍රණය වේ).

දෙවන අවස්ථාව නම්, එය longRunningTaskදැනටමත් ක්‍රියාත්මක කිරීම අවසන් කර ඇති අතර ප්‍රති result ලය ලබා ගත හැකිය. await longRunningTaskඅප වෙත ළඟා වන විට අපට දැනටමත් ප්‍රති result ලය ඇති බැවින් කේතය එකම ත්‍රෙඩ් එකක දිගටම ක්‍රියාත්මක වේ. (මෙම අවස්ථාවේදී කොන්සෝලය සඳහා මුද්‍රණ ප්‍රති result ලය). ඇත්ත වශයෙන්ම ඉහත උදාහරණය සඳහා මෙය එසේ නොවේ Task.Delay(1000).


67
අපට "Task.Delay (1000)" සමඟ "බලා සිටීම" ඇත්තේ ඇයි? LongRunningOperation async ක්‍රමයේදී?
බෙනිසන් සෑම්

4
odecodea එරික් ලිපර්ට්ගේ ලිපියට අදහස් දැක්වීමේදී ඔහු මෙම මාතෘකාවට හඳුන්වාදීමේ ලිපියක් සම්බන්ධ කළේය . එහිදී ඔහු DoEvents උපායමාර්ගය අසමසම-බලාපොරොත්තුව සමඟ සංසන්දනය කරයි
කැමිලෝ

14
En බෙනිසන් සෑම් නූල් ටිකක් පරණයි, නමුත් මට එකම ප්‍රශ්නය ඇති අතර පිළිතුරක් සොයමින් සිටියෙමි. "බලා සිටින්න" සඳහා හේතුව නම්, අපි "බලා සිටින්න" මඟ හැරියහොත් LongRunningOperationAsync () වහාම ආපසු එනු ඇත. ඇත්ත වශයෙන්ම අපි බලා‍පොරොත්තුව ඉවත් කළහොත් සම්පාදකයා අනතුරු ඇඟවීමක් කරනු ඇත. ස්ටීවන් ක්ලියරිගේ බ්ලොග් සටහන blog.stephencleary.com/2011/09/… නිර්මාණ සාකච්ඡාවල විශිෂ්ටත්වයක් ලබා දෙයි.
shellbypereira

73
සෑම අසින්ක් ක්‍රමයකම ඇතුළත රැඳී සිටීමට අවශ්‍ය නම්, සහ බලා සිටීම කළ හැක්කේ අසින්ක් සහිත ක්‍රමවේදයක් මත නම්, එය නතර වන්නේ කවදාද?
සැන්ටොස්

113
මෙම පිළිතුර පැහැදිලිවම වැරදිය. මෙම බොහෝ ඉහළ නැංවීම් බොහෝ පරිශීලකයින්ට වැරදි අවබෝධයක් ලබා දෙනු ඇත. එම්එස් ප්‍රලේඛනය පැහැදිලිවම පවසන්නේ, අසින්ක් භාවිතා කරන විට වෙනත් නූල් භාවිතා නොකරන බවයි. msdn.microsoft.com/en-us/library/mt674882.aspx කරුණාකර කවුරුහරි පිළිතුර නිවැරදි කරන්න. මේ නිසා මම දවස පුරාම නාස්ති කළා.
ක්‍රිෂ්ණා දීපක්

178

මගේ අවබෝධයෙන් අසින්ක් සහ බලා සිටින ප්‍රධාන දේවලින් එකක් වන්නේ කේතය ලිවීමට සහ කියවීමට පහසු කිරීමයි.

ඔවුන් අසමමුහුර්ත කේතය ලිවීමට සහ කියවීමට පහසු කරයි, ඔව්.

දිගුකාලීන තර්කනය සිදු කිරීම සඳහා පසුබිම් නූල් විහිදුවීම හා සමානද?

කොහෙත්ම නැහැ.

// මෙම ක්‍රමය 'අසින්ක්' ලෙස සලකුණු කළ යුත්තේ මන්දැයි මට තේරෙන්නේ නැත.

මෙම asyncමූල පදය සක්රීය awaitමූල පදය. එබැවින් භාවිතා කරන ඕනෑම ක්‍රමයක් awaitසලකුණු කළ යුතුය async.

DoSomethingAsync () ක්‍රමයෙන් තත්පර 5 ක නින්දෙන් පසුව මෙම රේඛාව ළඟා වේ. එය වහාම ළඟා විය යුතු නොවේද?

නැත, asyncක්‍රම වෙනත් ක්‍රමයකින් පෙරනිමියෙන් ක්‍රියාත්මක නොවන නිසා .

// මෙය ක්‍රියාත්මක වන්නේ පසුබිම් නූල් මතද?

නැත.


ඔබට මගේ async/ awaitහැඳින්වීම ප්‍රයෝජනවත් විය හැකිය . මෙම නිල MSDN හි ලේඛන ද අසාමාන්ය ලෙස හොඳ (විශේෂයෙන් වේ TAP කොටස), හා asyncකණ්ඩායම විශිෂ්ට නිවා නිතර අසන ප්රශ්න .


8
එබැවින් එය පසුබිම් නූල් මත ධාවනය නොවේ, නමුත් එය ද අවහිර නොකරයි. මෙය සිදුවිය හැක්කේ අසමමුහුර්ත API මඟින් නූල් සමඟ විහිළු කිරීම වෙනුවට ඇමතුම් ලබා ගැනීමෙනි. ඔබ (I / O, සොකට්, ..) මෙහෙයුමක් ආරම්භ කර ඔබේ දේවල් කිරීමට ආපසු යන්න. මෙහෙයුම සිදු කළ විට, මෙහෙයුම් පද්ධතිය නැවත ඇමතුමක් ලබා දෙනු ඇත. Node.js හෝ පයිතන් විකෘති රාමුව මෙයයි. ඔවුන්ට හොඳ පැහැදිලි කිරීමක්ද ඇත.
රෝමන් ප්ලීල්

4
"අසින්ක් යතුරුපදය මඟින් බලා සිටීමේ මූල පදය සක්‍රීය කරයි. එබැවින් බලා සිටීමේ ඕනෑම ක්‍රමයක් අසින්ක් ලෙස සලකුණු කළ යුතුය.", - නමුත් ඇයි? ක්‍රමය අසයික් ලෙස සලකුණු කළ යුත්තේ මන්දැයි තේරුම් ගැනීමට මෙම පිළිතුර උපකාරී නොවේ. මූල පද බලාපොරොත්තුවෙන් ඇතුළත බැලීමෙන් ක්‍රමවේදය අසමසම බව සම්පාදකයාට නිගමනය කළ නොහැකිද?
ස්ටැනිස්ලාව්

11
An ස්ටැනිස්ලාව්: මට බ්ලොග් සටහනක් ඇත.
ස්ටීවන් ක්ලියරි

5
යෝජිත පැහැදිලි කිරීම: නැත, asyncක්‍රම පෙරනිමියෙන් වෙනත් ත්‍රෙඩ් එකක ක්‍රියාත්මක නොවන නිසා . ඔබගේ උදාහරණයේ දී, Sleep()ඇමතුම DoSomethingAsync()වත්මන් නූල් අවහිර කරන අතර button1_Click()එය DoSomethingAsync()සම්පූර්ණ වන තෙක් ක්‍රියාත්මක වීම වළක්වයි . Thread.Sleep()ක්‍රියාත්මක වන නූල් අවහිර කරන අතරතුර ,Task.Delay() does not.
ඩේවිඩ්ආර්

2
PeterLarsen'CPH @ ': මෙහි මගේ පිළිතුර "අසමකාලීක නූල් වීමේදී සමාන නොවේ" වන අතර, "අසමකාලීක ක්රම තවත් නූල් මත ධාවනය වන නොවේ පෙරනිමියෙන් ", හා " Sleepතුළ සිටින asyncක්රමය තවත් නූල් මත ක්රියාත්මක නොවන". මේ සියල්ල සත්‍ය වන අතර ලියකියවිලි එකඟ වේ.
ස්ටීවන් ක්ලියරි

170

පැහැදිලි කිරීම

මෙන්න ඉහළ මට්ටමේ async/ ඉක්මන් උදාහරණයක් await. මෙයින් ඔබ්බට සලකා බැලිය යුතු තවත් බොහෝ තොරතුරු තිබේ.

සටහන: Task.Delay(1000)තත්පර 1 ක් වැඩ කිරීම අනුකරණය කරයි. මෙය බාහිර සම්පතකින් ප්‍රතිචාරයක් බලාපොරොත්තුවෙන් සිටීම සුදුසු යැයි මම සිතමි. අපගේ කේතය ප්‍රතිචාරයක් බලාපොරොත්තුවෙන් සිටින බැවින්, පද්ධතියට ධාවන කාර්යය පැත්තට හරවා එය අවසන් වූ පසු නැවත ඒ වෙත පැමිණිය හැකිය. මේ අතර, එම ත්‍රෙඩ් එකේ වෙනත් වැඩක් කළ හැකිය.

පහත උදාහරණයේ දී, පළමු කොටස හරියටම එය කරයි. එය සියලු කාර්යයන් වහාම ආරම්භ කරයි ( Task.Delayරේඛා) ඒවා පැත්තට හරවයි. await aඊළඟ පේළියට යාමට පෙර තත්පර 1 ප්‍රමාදය සිදු වන තුරු කේතය පේළියේ විරාමයක් ලබා දෙනු ඇත . සිට b, c, d, සහ eසියලු වාගේ නිශ්චිත එම අවස්ථාවේ දී ක්රියාත්මක ආරම්භa (තෙක් ඉවසා නොමැති වීම හේතුවෙන්), ඔවුන් මේ අවස්ථාවේ දී දළ වශයෙන් එම අවස්ථාවේ දී අවසන් කළ යුතුය.

පහත දැක්වෙන උදාහරණයේ දී, දෙවන කොටස කාර්යයක් ආරම්භ කර එය අවසන් වන තෙක් බලා සිටී (එය කරන්නේ එයයි await) පසුව සිදුකරන කාර්යයන් ආරම්භ කිරීමට පෙර. මෙහි සෑම පුනරාවර්තනයක්ම තත්පර 1 ක් ගතවේ. මෙම awaitවැඩසටහන pausing හා ඉදිරියට යාමට පෙර ප්රතිඵලය සඳහා නැවතී ඇත. පළමු හා දෙවන කොටස් අතර ඇති ප්‍රධාන වෙනස මෙයයි.

උදාහරණයක්

Console.WriteLine(DateTime.Now);

// This block takes 1 second to run because all
// 5 tasks are running simultaneously
{
    var a = Task.Delay(1000);
    var b = Task.Delay(1000);
    var c = Task.Delay(1000);
    var d = Task.Delay(1000);
    var e = Task.Delay(1000);

    await a;
    await b;
    await c;
    await d;
    await e;
}

Console.WriteLine(DateTime.Now);

// This block takes 5 seconds to run because each "await"
// pauses the code until the task finishes
{
    await Task.Delay(1000);
    await Task.Delay(1000);
    await Task.Delay(1000);
    await Task.Delay(1000);
    await Task.Delay(1000);
}
Console.WriteLine(DateTime.Now);

නිමැවුම්:

5/24/2017 2:22:50 PM
5/24/2017 2:22:51 PM (First block took 1 second)
5/24/2017 2:22:56 PM (Second block took 5 seconds)

සමමුහුර්තකරණය සම්බන්ධ අමතර තොරතුරු

සටහන: දේවල් මට ටිකක් මීදුම ලබා දෙන ස්ථානය මෙයයි, එබැවින් මම කිසියම් දෙයක් වැරදියි නම්, කරුණාකර මාව නිවැරදි කරන්න, මම පිළිතුර යාවත්කාලීන කරමි. මෙය ක්‍රියාත්මක වන ආකාරය පිළිබඳ මූලික අවබෝධයක් තිබීම වැදගත් නමුත් ඔබ කිසි විටෙකත් භාවිතා නොකරන තාක් කල් ඒ පිළිබඳ විශේෂ expert යෙකු නොවී ඔබට ලබා ගත හැකිය ConfigureAwait(false), නමුත් ඔබට ප්‍රශස්තිකරණය සඳහා යම් අවස්ථාවක් අහිමි වනු ඇතැයි මම සිතමි.

මෙහි එක් අංගයක් ඇත async/ awaitසංකල්පය ග්‍රහණය කර ගැනීමට තරමක් උපක්‍රමශීලී වේ. මෙම උදාහරණයේ දී, මේ සියල්ල සිදුවන්නේ එකම නූල් මත ය (හෝ අවම වශයෙන් එය සම්බන්ධයෙන් එකම නූල් ලෙස පෙනෙන දේ SynchronizationContext). පෙරනිමියෙන්, awaitඑය ක්‍රියාත්මක වූ මුල් නූල් වල සමමුහුර්ත කිරීමේ සන්දර්භය යථා තත්වයට පත් කරනු ඇත. උදාහරණයක් ලෙස, ASP.NET හි ඔබටHttpContext හි ඉල්ලීමක් පැමිණි විට එය නූල් එකකට බැඳී ඇත. මෙම සන්දර්භය තුළ මුල් HTTP ඉල්ලීමට විශේෂිත වූ දෑ අඩංගු වේ, එනම් මුල් ඉල්ලීම් වස්තුව වැනි භාෂාව, IP ලිපිනය, ශීර්ෂ යනාදිය ඇත. ඔබ යමක් සැකසීමෙන් අඩක් නූල් මාරු කළහොත්, ඔබට වෙනත් වස්තුවකින් මෙම වස්තුවෙන් තොරතුරු පිටතට ගැනීමට උත්සාහ කළ හැකියHttpContextඑය විනාශකාරී විය හැකිය. ඔබ කිසිවක් සඳහා සන්දර්භය භාවිතා නොකරන බව ඔබ දන්නේ නම්, ඔබට ඒ ගැන "සැලකිල්ලක් නොදක්වා" තෝරා ගත හැකිය. මෙය මූලික වශයෙන් ඔබේ කේතය සන්දර්භය ගෙන ඒමකින් තොරව වෙනම ත්‍රෙඩ් එකක ධාවනය කිරීමට ඉඩ දෙයි.

ඔබ මෙය සාක්ෂාත් කරගන්නේ කෙසේද? පෙරනිමියෙන්, await a;කේතය ඇත්ත වශයෙන්ම ඔබට සන්දර්භය ග්‍රහණය කර ප්‍රතිස්ථාපනය කිරීමට අවශ්‍ය යැයි උපකල්පනයක් කරයි:

await a; //Same as the line below
await a.ConfigureAwait(true);

මුල් සන්දර්භය නොමැතිව ප්‍රධාන කේතය නව ත්‍රෙඩ් එකක දිගටම කරගෙන යාමට ඔබට අවශ්‍ය නම්, ඔබ සත්‍යය වෙනුවට අසත්‍යය භාවිතා කරන අතර එමඟින් සන්දර්භය යථා තත්වයට පත් කිරීම අවශ්‍ය නොවන බව දනී.

await a.ConfigureAwait(false);

වැඩසටහන විරාමයක් ලබා දීමෙන් පසුව, එය වෙනස් සන්දර්භයක් සහිත සම්පූර්ණයෙන්ම වෙනස් ත්‍රෙඩ් එකක දිගටම පැවතිය හැකිය . කාර්ය සාධනය වැඩිදියුණු කිරීම පැමිණෙන්නේ මෙතැනිනි - එය ආරම්භ වූ මුල් සන්දර්භය යථා තත්වයට පත් නොකර ඕනෑම පවතින නූල් මත දිගටම කරගෙන යා හැකිය.

මේ දේවල් අවුල් සහගතද? අපාය ඔව්! ඔබට එය තේරුම් ගත හැකිද? සමහරවිට! ඔබ සංකල්ප පිළිබඳ අවබෝධයක් ලබා ගත් පසු, ස්ටීවන් ක්ලියරිගේ පැහැදිලි කිරීම් වෙත යොමු වන්න, එය දැනටමත් async/ awaitදැනටමත් තාක්ෂණික අවබෝධයක් ඇති අයෙකු වෙත වැඩි නැඹුරුවක් දක්වයි .


මෙම කාර්යයන් සියල්ලම නැවත ලබා දෙන්නේ නම් සහ මම පළමු කාර්යයේ ප්‍රති result ලය දෙවන කාර්යයේදී භාවිතා කරන්නේ නම් (හෝ යම් ගණනය කිරීමක්) එය වැරදිද?
veerendra gupta

3
@veerendragupta ඔව්. එම අවස්ථාවේ දී ඒවා සමමුහුර්තව ධාවනය නොකිරීමට ඔබ දැනුවත්ව තෝරා ගනු ඇත (ඒවා අසමමුහුර්ත නොවන නිසා). වින්‍යාසකරණ සන්දර්භය පිළිබඳව මා මෙහි නොයන තවත් කරුණු කිහිපයක් තිබේ
ජෝ ෆිලිප්ස්

ඉතින් await MethodCall()නිරපේක්ෂ නාස්තියක්ද? ඔබටත් await/ async?
විතානි

2
Oc ජොසී තරමක් නොවේ. ඔබ අමතන විට await, මම හිතන්නේ එය රඳවා තබා ගැනීම වෙනුවට නූල් පොකුණට මුදා හරිනු ඇත. කාර්යය නැවත පැමිණීමට බලා සිටින අතරතුර මෙය වෙනත් තැනක භාවිතයට ලබා ගත හැකිය
ජෝ ෆිලිප්ස්

2
Oe ජෝ ෆිලිප්ස් මම හිතන්නේ ඔබ කියූ දෙය අසින්ක් / බලා සිටීමේ සාරයයි. ඇමතුම් නූල් නිදහස් කර ඇති අතර යන්ත්‍රයේ වෙනත් ක්‍රියාවලි සඳහා භාවිතා කළ හැකිය. අපේක්ෂිත ඇමතුම සම්පුර්ණ වූ විට, අමතන්නා මුලින් ආරම්භ කළ දේ නැවත ආරම්භ කිරීම සඳහා නව නූලක් භාවිතා කරයි. අමතන්නා තවමත් බලා සිටියි, නමුත් වාසිය නම් මේ අතර නූල් නිදහස් වීමයි. එය අසින්ක් / රැඳී සිටීමේ වාසියද?
බොබ් හෝන්

150

අනෙක් පිළිතුරු වලට අමතරව, බලා සිටීම දෙස බලන්න (C # යොමුව)

සහ වඩාත් නිශ්චිතවම ඇතුළත් කර ඇති උදාහරණයේ දී, එය ඔබගේ තත්වය ටිකක් පැහැදිලි කරයි

පහත දැක්වෙන වින්ඩෝස් පෝරම උදාහරණයෙන් දැක්වෙන්නේ WaitAsynchronouslyAsync යන අසින්ක් ක්‍රමයේදී අපේක්ෂාව භාවිතා කිරීමයි. එම ක්‍රමයේ හැසිරීම WaitSynchronously හි හැසිරීම හා සසඳන්න. යම් කාර්යයක් සඳහා බලා සිටීමේ ක්‍රියාකරුවෙකු නොමැතිව, වේට්සින්ක්‍රොනික් ලෙස අර්ථ දැක්වීමේදී අසින්ක් විකරණකාරකය භාවිතා කර තිබියදීත්, ත්‍රෙඩ් වෙත ඇමතුමක් ලබා දී තිබියදීත් සමමුහුර්තව ක්‍රියාත්මක වේ.

private async void button1_Click(object sender, EventArgs e)
{
    // Call the method that runs asynchronously.
    string result = await WaitAsynchronouslyAsync();

    // Call the method that runs synchronously.
    //string result = await WaitSynchronously ();

    // Display the result.
    textBox1.Text += result;
}

// The following method runs asynchronously. The UI thread is not
// blocked during the delay. You can move or resize the Form1 window 
// while Task.Delay is running.
public async Task<string> WaitAsynchronouslyAsync()
{
    await Task.Delay(10000);
    return "Finished";
}

// The following method runs synchronously, despite the use of async.
// You cannot move or resize the Form1 window while Thread.Sleep
// is running because the UI thread is blocked.
public async Task<string> WaitSynchronously()
{
    // Add a using directive for System.Threading.
    Thread.Sleep(10000);
    return "Finished";
}

4
පිළිතුරට ස්තූතියි. නමුත් WaitAsynchronouslyAsync () වෙනම නූලක් මත ක්‍රියාත්මක වේද?
ඩෑන් ඩිනූ

33
මම විශ්වාස කරමි, බලා‍පොරොත්තු ප්‍රකාශනය මඟින් එය ක්‍රියාත්මක වන නූල් අවහිර නොකරයි. ඒ වෙනුවට, එය අපේක්ෂිත කර්තව්‍යයේ අඛණ්ඩ පැවැත්මක් ලෙස සම්පාදකයා විසින් ඉතිරි අසින්ක් ක්‍රමයට අත්සන් කිරීමට හේතු වේ. පාලනය පසුව අසින්ක් ක්‍රමයේ අමතන්නා වෙත නැවත පැමිණේ. කාර්යය සම්පුර්ණ වූ විට, එය අඛණ්ඩව පවත්වාගෙන යා යුතු අතර අසින්ක් ක්‍රමය ක්‍රියාත්මක කිරීම එය නතර කළ තැන නැවත ආරම්භ වේ.
ඇඩ්‍රියන් ස්ටැන්ඩර්

15
අනුව මෙම MSDN හි ලිපිය , "මෙම අසමකාලීක හා ඉදිරියේදී බලාපොරොත්තු වන්න ප්රධාන වචන නිර්මාණය කළ අතිරේක නූල් හේතුව නැහැ .... ක අසමකාලීක ක්රමය එහි ම නූල් මත ක්රියාත්මක නොවන". මගේ අවබෝධය නම්, මූල පද බලාපොරොත්තුවෙන් සිටින විට, දිගු මෙහෙයුම් අවසන් වන තෙක් බලා සිටින අතරතුර හැකි සෑම ස්වාධීන කේතයක්ම ක්‍රියාත්මක කිරීමට ඉඩ දීම සඳහා රාමුව ඉදිරියට (අමතන්නා වෙත) මඟ හැරේ. මම හිතන්නේ එයින් අදහස් වන්නේ සියලු ස්වාධීන කේත ක්‍රියාත්මක වූ පසු, දිගු ක්‍රියාකාරිත්වය නැවත නොපැමිණියේ නම් එය අවහිර වනු ඇති බවයි. මම දැන් මෙය ඉගෙන ගන්නවා.
Vimes

11
@astander එය වැරදිය. එය වෙනත් ත්‍රෙඩ් එකක ක්‍රියාත්මක නොවේ . එය Task.Delayගින්නෙන් භාවිතා කරන කාලරාමුව හැඳින්විය යුතු අඛණ්ඩතාව (ඉතිරි ක්‍රමවේදය) උපලේඛනගත කිරීමකි .
MgSam

2
නින්ද නිසා මෙම පිළිතුර වැරදිය. භාරගත් කාර්යය සමඟ පිළිගත් පිළිතුර බලන්න. දිනය (1000); නිවැරදි හැසිරීමක් ඇති.
ජරෙඩ් යාවත්කාලීන කිරීම

64

ඉහත පැහැදිලි කිරීම් සරල කොන්සෝල වැඩසටහනක පෙන්වයි:

class Program
{
    static void Main(string[] args)
    {
        TestAsyncAwaitMethods();
        Console.WriteLine("Press any key to exit...");
        Console.ReadLine();
    }

    public async static void TestAsyncAwaitMethods()
    {
        await LongRunningMethod();
    }

    public static async Task<int> LongRunningMethod()
    {
        Console.WriteLine("Starting Long Running method...");
        await Task.Delay(5000);
        Console.WriteLine("End Long Running method...");
        return 1;
    }
}

ප්‍රතිදානය:

Starting Long Running method...
Press any key to exit...
End Long Running method...

මේ අනුව,

  1. ප්රධාන දිගුකාලීන ක්රමය හරහා ආරම්භ TestAsyncAwaitMethodsවේ. එය වත්මන් නූල් නතර නොකර වහාම ආපසු පැමිණෙන අතර අපට වහාම 'පිටවීමට ඕනෑම යතුරක් ඔබන්න' පණිවිඩය පෙනේ
  2. මේ සියල්ල අතරතුර, LongRunningMethodඑය පසුබිමේ ධාවනය වේ. එය සම්පුර්ණ වූ පසු, ත්‍රෙඩ්පූල් හි තවත් නූලක් මෙම සන්දර්භය තෝරාගෙන අවසාන පණිවිඩය පෙන්වයි

මේ අනුව, නූල් අවහිර නොකෙරේ.


"පිටවීමට ඕනෑම යතුරක් ඔබන්න ..." ප්‍රතිදානයේ කුමන කොටසේ පෙන්වනු ඇත්ද?
StudioX

1
(ආපසු 1) හි භාවිතය කුමක්ද? එය අවශ්‍යද?
StudioX

1
UdStudioX මම හිතන්නේ එයට ආපසු වර්ගයේ පූර්ණ සංඛ්‍යාවක් තිබිය යුතුයි
කුබා ඩෝ

මෙම return 1කොටස තවත් පැහැදිලි කිරීමක් ලැබිය යුතු යැයි මම සිතමි : awaitයතුරුපදය මඟින් යටින් පවතින වර්ගය Task<T>කෙලින්ම ආපසු ලබා දීමට ඉඩ සලසයි , එමඟින් ඔබගේ පිටවීමේ කේතය අපේක්ෂිත / අසින්ක් ලෝකයට අනුවර්තනය වීම පහසු කරයි . එහෙත්, ඔබ නැති එය නැවත කිරීමට එයට හැකිය, අගය ආපසු Taskඑය සමමුහුර්ත කට සමාන වනු ඇති නැවත හැරී වර්ගය, නියම තොරව voidක්රමය. C # async voidක්‍රම වලට ඉඩ දෙන බව සිතන්න , නමුත් ඔබ සිදුවීම් හසුරුවන්නන් සමඟ කටයුතු නොකරන්නේ නම් එසේ කිරීමෙන් වැළකී සිටිය යුතුය.
ක්‍රිස්ටියානෝ කිස්

43

මම හිතන්නේ ඔබ නරක උදාහරණයක් තෝරාගෙන ඇත System.Threading.Thread.Sleep

කාර්යයේ ලක්ෂ්‍යය asyncනම් ප්‍රධාන නූල් අගුළු නොගෙන පසුබිමක ක්‍රියාත්මක කිරීමට ඉඩ දීමයිDownloadFileAsync

System.Threading.Thread.Sleep "සිදු කෙරෙන" දෙයක් නොවේ, එය නිදා ගනී, එබැවින් ඔබේ ඊළඟ පේළිය තත්පර 5 කට පසුව ළඟා වේ ...

මෙම ලිපිය කියවන්න, එය හොඳ සංකල්පයක් asyncසහ awaitසංකල්පයක් යැයි මම සිතමි : http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx


4
නින්ද නරක උදාහරණයක් නමුත් බාගැනීම හොඳ උදාහරණයකි. මම Thread දකින විට එය FooBar ආකාරයේ දෙයක් වගේ ය. නින්ද මට තේරෙනවා යම් කාර්යයක් ඇති බව. මම හිතන්නේ ඔහුගේ ප්‍රශ්නය
අදාළයි

2
B අබ්දුරාහිම් Thread.Sleepවිසින් නූල් අවහිර කරයි (නූල් වලට වෙනත් කිසිවක් කළ නොහැක. පිළිබඳ පැමිණිල්ලේ දී DownloadFileAsync, පිළිතුරු දුරස්ථ සේවාදායකය ලැබෙන තුරු නූල් වෙන දෙයක් ගොස් කරන්න පුළුවන්. Task.Delayඅසමමුහුර්ත ක්‍රමයක් තුළ “කාලය ගතවන යම් කාර්යයක්” සඳහා වඩා හොඳ ස්ථානගත කිරීමක් වන්නේ එය ඇත්ත වශයෙන්ම අසමමුහුර්ත බැවිනි.
ගේබ්‍රියෙල් ලුසි

1
Ab ගේබ්‍රියෙල්ලූසි මගේ විරෝධය ප්‍රමාදයට එදිරිව නින්ද ගැන නොවේ; ඔබේ පිළිතුර ස්ට්රෝමන් පිළිතුරක් මෙන් පෙනේ; ඔබ මෙය ප්‍රශ්නයට අදහස් දැක්වීමක් ලෙස තැබුවහොත් එය මට විරුද්ධ විය හැකි කිසිවක් නොවනු ඇත, නමුත් පිළිතුරක් ලෙස එය ගඳ සුවඳක් මෙන් දැනේ. මම හිතන්නේ ඔහු / ඇය කළ යුතු සියලුම ඇමතුම් පවා ඇමතුම් අවහිර කරනු ඇත. එය සියලු අරමුණු අවලංගු නොකරනු ඇත ... ඉතිරි සියල්ලම සින්ටැක්ටික් සීනි වනු ඇත, එය වලංගු අවස්ථාවක් ලෙස සලකනු ලැබේ,
අබ්දුල් රහීම්

2
මෙය මගේ පිළිතුර නොවේ. නමුත් ඔබේ අදහස ආමන්ත්‍රණය කිරීම සඳහා: එය ක්‍රමයේ අරමුණ මත රඳා පවතී. ඔහුට ඇමතීමට ක්‍රමයක් අවශ්‍ය නම් ඔහු සාර්ථක විය. නමුත් මේ අවස්ථාවේ දී ඔහු උත්සාහ කළේ අසමමුහුර්තව ක්‍රියාත්මක වන ක්‍රමවේදයක් සැකසීමට ය. ඔහු එය කළේ යතුර භාවිතා කිරීමෙන් පමණි async. නමුත් ඔහුගේ ක්‍රමය තවමත් සමමුහුර්තව ක්‍රියාත්මක වූ අතර, මෙම පිළිතුර එයට හේතුව පැහැදිලි කරයි: ඔහු ඇත්ත වශයෙන්ම කිසිදු අසමමුහුර්ත කේතයක් ක්‍රියාත්මක නොකළ නිසා. සලකුණු කරන ලද ක්‍රම asyncඔබ awaitඅසම්පූර්ණ වන තෙක් සමමුහුර්තව ක්‍රියාත්මක Taskවේ. නොමැති awaitනම්, ක්‍රමය සමමුහුර්තව ක්‍රියාත්මක වන අතර සම්පාදකයා ඔබට ඒ ගැන අනතුරු අඟවයි.
ගේබ්‍රියෙල් ලුසි

29

වේගවත්ම ඉගෙනීම සඳහා ..

  • ක්‍රම ක්‍රියාත්මක කිරීමේ ප්‍රවාහය තේරුම් ගන්න (රූප සටහනක් සමඟ): මිනිත්තු 3 යි

  • ප්‍රශ්න ස්වයං විචාරය (ඉගෙනීම සඳහා): මිනිත්තු 1 යි

  • සින්ටැක්ස් සීනි හරහා ඉක්මනින් යන්න: මිනිත්තු 5 යි

  • සංවර්ධකයෙකුගේ ව්‍යාකූලත්වය බෙදා ගන්න: මිනිත්තු 5 යි

  • ගැටලුව: සාමාන්‍ය කේතය තථ්‍ය-ලෝක ක්‍රියාත්මක කිරීම අසින්ක් කේතයට ඉක්මනින් වෙනස් කරන්න: මිනිත්තු 2 යි

  • ඊළඟට කොහෙද?

ක්‍රම ක්‍රියාත්මක කිරීමේ ප්‍රවාහය තේරුම් ගන්න (රූප සටහනක් සමඟ): මිනිත්තු 3 යි

මෙම රූපයේ, # 6 වෙත අවධානය යොමු කරන්න (වැඩි යමක් නැත) රූප විස්තරය මෙහි ඇතුළත් කරන්න

# 6 පියවරේදී: ක්‍රියාත්මක නොවීම නිසා ක්‍රියාත්මක කිරීම මෙහි නතර විය. එය දිගටම කරගෙන යාමට getStringTask (ආකාරයේ ශ්‍රිතයක්) වෙතින් ප්‍රති result ලයක් අවශ්‍ය වේ. එම නිසා, එය awaitඑහි ප්‍රගතිය අත්හිටුවීමට සහ ඇමතුමට පාලනය (අස්වැන්න) ලබා දීමට ක්‍රියාකරුවෙකු භාවිතා කරයි (මෙම ක්‍රමයේ). GetStringTask සඳහා සත්‍ය ඇමතුම මීට පෙර # 2 දී සිදු කරන ලදි. # 2 හි දී ප්‍රති string ලයක් ලබා දෙන බවට පොරොන්දුවක් දෙන ලදි. නමුත් එය ප්‍රති result ලය ලබා දෙන්නේ කවදාද? අපි (# 1: AccessTheWebAsync) නැවත 2 වන ඇමතුමක් ලබා ගත යුතුද? ප්‍රති result ලය ලැබෙන්නේ කාටද, # 2 (ඇමතුම් ප්‍රකාශය) හෝ # 6 (ප්‍රකාශය බලාපොරොත්තුවෙන්)

AccessTheWebAsync () හි බාහිර ඇමතුම්කරු ද දැන් බලා සිටී. එබැවින් අමතන්නා AccessTheWebAsync සඳහා බලා සිටින අතර AccessTheWebAsync මේ මොහොතේ GetStringAsync සඳහා බලා සිටී. සිත්ගන්නා කරුණ නම් AccessTheWebAsync බලා සිටීමට පෙර යම් වැඩක් (# 4) කර ඇති අතර සමහර විට බලා සිටීමෙන් කාලය ඉතිරි කර ගත හැකිය. බහු කාර්යයන් සඳහා එකම නිදහස බාහිර ඇමතුම්කරුට (සහ දාමයේ සිටින සියලුම ඇමතුම්කරුවන්ට) ලබා ගත හැකි අතර මෙය මෙම 'අසින්ක්' හි විශාලතම ප්ලස් වේ! එය සමමුහුර්ත හෝ සාමාන්‍ය යැයි ඔබට හැඟේ නමුත් එය එසේ නොවේ.

මතක තබා ගන්න, ක්‍රමය දැනටමත් ආපසු ලබා දී ඇත (# 2), එයට නැවත පැමිණිය නොහැක (දෙවන වරටත් නැත). ඉතින් අමතන්නා දැන ගන්නේ කෙසේද? එය සියල්ලම කාර්යයන් වේ! කාර්යය සම්මත විය. කාර්යය සඳහා බලා සිටියේය (ක්රමය නොවේ, වටිනාකම නොවේ). කාර්යය තුළ අගය සැකසෙනු ඇත. කාර්ය තත්වය සම්පූර්ණ කිරීමට සකසනු ඇත. අමතන්නා කාර්යය නිරීක්ෂණය කරයි (# 6). එබැවින් 6 # යනු ප්‍රති / ලය ලැබෙන්නේ කොහෙන්ද / කවුද යන්නට පිළිතුරයි. වැඩිදුර කියවීම පසුව මෙහි .

ඉගෙනීම සඳහා ප්‍රශ්න ස්වයං විමර්ශනය: මිනිත්තු 1 යි

ප්‍රශ්නය ටිකක් සකස් කරමු:

ඒ කෙසේ ද, භාවිතා කිරීමට විට හා ? asyncawait Tasks

ඉගෙනීම Taskඅනෙක් දෙක ස්වයංක්‍රීයව ආවරණය කරන නිසා (සහ ඔබේ ප්‍රශ්නයට පිළිතුරු සපයයි)

සින්ටැක්ස් සීනි හරහා ඉක්මනින් යන්න: මිනිත්තු 5 යි

  • පරිවර්තනය කිරීමට පෙර (මුල් ක්‍රමය)
internal static int Method(int arg0, int arg1)
        {
            int result = arg0 + arg1;
            IO(); // Do some long running IO.
            return result;
        }
  • ඉහත ක්‍රමය ඇමතීමට කාර්ය සාධක සහිත ක්‍රමයක්
internal static Task<int> MethodTask(int arg0, int arg1)
    {
        Task<int> task = new Task<int>(() => Method(arg0, arg1));
        task.Start(); // Hot task (started task) should always be returned.
        return task;
    }

අපි බලා සිටියේ හෝ අසමමුහුර්තව සඳහන් කළාද? නැත. ඉහත ක්‍රමය අමතන්න, ඔබට අධීක්ෂණය කළ හැකි කාර්යයක් ලැබෙනු ඇත. කාර්යය නැවත පැමිණෙන්නේ කුමක් දැයි ඔබ දැනටමත් දන්නවා .. පූර්ණ සංඛ්‍යාවක්.

  • කාර්යයක් ඇමතීම තරමක් උපක්‍රමශීලී වන අතර මූල පද දිස්වීමට පටන් ගන්නේ එවිටය. අපි MethodTask () අමතමු
internal static async Task<int> MethodAsync(int arg0, int arg1)
    {
        int result = await HelperMethods.MethodTask(arg0, arg1);
        return result;
    }

ඉහත කේතය පහත රූපයේ එකතු කර ඇත: රූප විස්තරය මෙහි ඇතුළත් කරන්න

  1. අපි 'බලා සිටිමු' කාර්යය අවසන් කිරීමට. එබැවින්await
  2. අපි බලා සිටීම භාවිතා කරන බැවින්, අප භාවිතා කළ යුතුය async (අනිවාර්ය සින්ටැක්ස්)
  3. සමග MethodAsync Async උපසර්ගය සමඟ (කේතීකරණ ප්‍රමිතිය)

awaitතේරුම් ගැනීමට පහසු නමුත් ඉතිරි දෙක ( async, Async) නොවිය හැක :). හොඳයි, එය සම්පාදකයාට වැඩි අර්ථයක් ලබා දිය යුතුය. වැඩිදුර කියවීම පසුව මෙහි

එබැවින් කොටස් 2 ක් ඇත.

  1. 'කාර්යය' සාදන්න
  2. කාර්යය ඇමතීමට සින්ටැක්ටික් සීනි සාදන්න ( await+async)

මතක තබා ගන්න, අපට AccessTheWebAsync () වෙත බාහිර ඇමතුමක් ලබා දී ඇති අතර එම ඇමතුමද ඉතිරි නොවේ ... එනම් එයටද එයම අවශ්‍ය await+asyncවේ. දාමය දිගටම. නමුත් සෑම විටම aTask එක් කෙළවරක .

සියල්ල හරි, නමුත් එක් සංවර්ධකයෙක් # 1 (කාර්යය) අතුරුදහන් වීම දැක පුදුමයට පත් විය ...

සංවර්ධකයෙකුගේ ව්‍යාකූලත්වය බෙදා ගන්න: මිනිත්තු 5 යි

සංවර්ධකයෙකු ක්‍රියාත්මක නොකිරීමේ වැරැද්දක් කර ඇති Taskනමුත් එය තවමත් ක්‍රියාත්මක වේ! මෙහි ඇති පිළිගත් පිළිතුර සහ ප්‍රශ්නය තේරුම් ගැනීමට උත්සාහ කරන්න . ඔබ කියවා සම්පූර්ණයෙන් තේරුම් ගෙන ඇතැයි සිතමි. සාරාංශය නම්, අපට 'කාර්යය' නොපෙනේ / ක්‍රියාත්මක නොවිය හැකි නමුත් එය දෙමව්පියන් / ආශ්‍රිත පන්තියක කොතැනක හෝ ක්‍රියාත්මක වේ. අපගේ උදාහරණයේ MethodAsync()දී Task( MethodTask()) අප විසින්ම එම ක්‍රමය ක්‍රියාත්මක කිරීමට වඩා දැනටමත් ඉදිකර ඇති කැඳවීමක් පහසුය . බොහෝ සංවර්ධකයින්ට ඔවුන්ගේ හිස එසවීම දුෂ්කර යTasksකේතයක් අසමමුහුර්ත එකක් බවට පරිවර්තනය කරන අතරම එහා මෙහා .

ඉඟිය: දුෂ්කරතාවය පිටතින් ලබා ගැනීම සඳහා දැනට පවතින අසින්ක් ක්‍රියාත්මක කිරීමක් (වැනි MethodAsyncහෝ ToListAsync) සොයා ගැනීමට උත්සාහ කරන්න . එබැවින් අපට අවශ්‍ය වන්නේ අසින්ක් සමඟ ගනුදෙනු කර බලා සිටීම පමණි (එය සාමාන්‍ය කේතයට පහසු සහ තරමක් සමාන ය)

ගැටළුව: සාමාන්‍ය කේතය සැබෑ ලෝකයේ ක්‍රියාත්මක කිරීම අසින්ක් මෙහෙයුමට ඉක්මනින් වෙනස් කරන්න: මිනිත්තු 2 යි

දත්ත ස්ථරයේ පහත දැක්වෙන කේත රේඛාව කැඩීමට පටන් ගත්තේය (බොහෝ ස්ථාන). අපගේ කේත සමහරක් .Net frame 4.2. * සිට .Net core දක්වා යාවත්කාලීන කළ බැවිනි. යෙදුම පුරා පැය 1 කින් මෙය නිවැරදි කිරීමට අපට සිදු විය!

var myContract = query.Where(c => c.ContractID == _contractID).First();

පහසුයි!

  1. අපි EntityFramework nuget පැකේජය ස්ථාපනය කළේ එයට QueryableExtensions ඇති බැවිනි. නැතහොත් වෙනත් වචන වලින් කිවහොත් එය අසින්ක් ක්‍රියාත්මක කිරීම (කර්තව්‍යය) කරයි, එබැවින් අපට සරල Asyncහාawait කේත වලින් .
  2. namespace = Microsoft.EntityFrameworkCore

ඇමතුම් කේත රේඛාව මේ ආකාරයට වෙනස් වී ඇත

var myContract = await query.Where(c => c.ContractID == _contractID).FirstAsync();
  1. ක්‍රම අත්සන වෙනස් කර ඇත

Contract GetContract(int contractnumber)

වෙත

async Task<Contract> GetContractAsync(int contractnumber)

  1. ඇමතුම් ක්‍රමයටද බලපෑමක් ඇති විය: GetContractAsync(123456);ලෙස හැඳින්වේGetContractAsync(123456).Result;

  2. අපි එය විනාඩි 30 කින් සෑම තැනකම වෙනස් කළා!

නමුත් ගෘහ නිර්මාණ ශිල්පියා අපට පැවසුවේ මේ සඳහා පමණක් EntityFramework පුස්තකාලය භාවිතා නොකරන ලෙසයි! අපොයි! නාට්‍යය! ඉන්පසු අපි අභිරුචි කාර්ය ක්‍රියාත්මක කිරීමක් (යූක්) සිදු කළෙමු. ඔබ දන්නේ කෙසේද. තවමත් පහසුයි! .. යූක් ..

ඊළඟට කොහෙද? ඒඑස්පී නෙට් කෝර් හි සමමුහුර්ත ඇමතුම් අසමමුහුර්ත බවට පරිවර්තනය කිරීම ගැන අපට නැරඹිය හැකි අපූරු ඉක්මන් වීඩියෝවක් තිබේ , සමහර විට මෙය කියවීමෙන් පසු යමෙකු යා හැකි දිශාව විය හැකිය.


අපූරු පිළිතුර! මෙය මට ටොන් එකක් උදව් කළා
cklimowski

1
හොඳ පිළිතුරක්. (අ) EntityFrameWork => EntityFramework දී ආවරණයක් ".NET Framework 4.2" (මම දන්නා එවැනි අනුවාදය, පවතී) (ආ) සඳහන්: ඔබ වැනි කුඩා දේවල් කිහිපයක් විසින් අදාල කරුණ නිවැරදි කිරීමට ඔබට අවශ්ය විය හැකිය
immitev

24

අනුගමනය කරන අයට එය පැහැදිලි කිරීම සඳහා ඉක්මන් කොන්සෝල වැඩසටහනක් මෙන්න. මෙම TaskToDoක්‍රමය ඔබේ දිගුකාලීන ක්‍රමය වන අතර එය ඔබට අසයික් කිරීමට අවශ්‍ය වේ. එය අසමමුහුර්තව ධාවනය කිරීම TestAsyncක්‍රමවේදය මඟින් සිදු කෙරේ . පරීක්ෂණ ලූප ක්‍රමය මඟින් TaskToDoකාර්යයන් හරහා දිවෙන අතර ඒවා අසමසම ලෙස ක්‍රියාත්මක වේ. ප්‍රති run ල වලදී ඒවා ධාවනයේ සිට ධාවනය දක්වා එකම අනුපිළිවෙලින් සම්පූර්ණ නොවන නිසා ඔබට දැක ගත හැකිය - ඒවා සම්පුර්ණ වූ විට ඒවා කොන්සෝලය UI නූල් වෙත වාර්තා කරයි. සරල, නමුත් මම සිතන්නේ සරල උදාහරණ රටාවේ හරය වඩා සම්බන්ධ උදාහරණ වලට වඩා හොඳින් ගෙන එයි:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace TestingAsync
{
    class Program
    {
        static void Main(string[] args)
        {
            TestLoops();
            Console.Read();
        }

        private static async void TestLoops()
        {
            for (int i = 0; i < 100; i++)
            {
                await TestAsync(i);
            }
        }

        private static Task TestAsync(int i)
        {
            return Task.Run(() => TaskToDo(i));
        }

        private async static void TaskToDo(int i)
        {
            await Task.Delay(10);
            Console.WriteLine(i);
        }
    }
}

16

මෙහි සියලු පිළිතුරු භාවිතා Task.Delay()හෝ වෙනත් ඉදි සමහර asyncඋත්සවය. නමුත් එම උදාහරණ කිසිවක් භාවිතා නොකරන මගේ උදාහරණය මෙන්න async:

// Starts counting to a large number and then immediately displays message "I'm counting...". 
// Then it waits for task to finish and displays "finished, press any key".
static void asyncTest ()
{
    Console.WriteLine("Started asyncTest()");
    Task<long> task = asyncTest_count();
    Console.WriteLine("Started counting, please wait...");
    task.Wait(); // if you comment this line you will see that message "Finished counting" will be displayed before we actually finished counting.
    //Console.WriteLine("Finished counting to " + task.Result.ToString()); // using task.Result seems to also call task.Wait().
    Console.WriteLine("Finished counting.");
    Console.WriteLine("Press any key to exit program.");
    Console.ReadLine();
}

static async Task<long> asyncTest_count()
{
    long k = 0;
    Console.WriteLine("Started asyncTest_count()");
    await Task.Run(() =>
    {
        long countTo = 100000000;
        int prevPercentDone = -1;
        for (long i = 0; i <= countTo; i++)
        {
            int percentDone = (int)(100 * (i / (double)countTo));
            if (percentDone != prevPercentDone)
            {
                prevPercentDone = percentDone;
                Console.Write(percentDone.ToString() + "% ");
            }

            k = i;
        }
    });
    Console.WriteLine("");
    Console.WriteLine("Finished asyncTest_count()");
    return k;
}

2
ඔබට ස්තුතියි! බලා සිටීම වෙනුවට ඇත්ත වශයෙන්ම යම් වැඩක් කරන පළමු පිළිතුර.
ජෙෆ්න්

පෙන්වීමට ස්තූතියි task.Wait();සහ එය නිරය වළක්වා ගැනීමට / නිරය බලාපොරොත්තුවෙන් සිටීමට භාවිතා කරන්නේ කෙසේද: පී
එන්කෝඩරය

14

අසින්ක් සහ සරල පැහැදිලි කිරීමක් බලාපොරොත්තුවෙන් සිටින්න

සරල ප්‍රතිසමයක්

පුද්ගලයෙකු බලා සිටිය හැකිය ඔවුන්ගේ උදෑසන දුම්රිය . ඔවුන් දැනට කරමින් සිටින ඔවුන්ගේ මූලික කාර්යය මෙය බැවින් ඔවුන් කරන්නේ මෙයයි. (සමමුහුර්ත වැඩසටහන්කරණය (ඔබ සාමාන්‍යයෙන් කරන දේ!))

තවත් අය දුම්රියක් බොමින් කෝපි පානය කරන අතරතුර ඔවුන්ගේ උදේ දුම්රිය එනතුරු බලා සිටිය හැකිය . (අසමමුහුර්ත වැඩසටහන්කරණය)

අසමමුහුර්ත වැඩසටහන්කරණය යනු කුමක්ද?

අසමමුහුර්ත ක්‍රමලේඛනය යනු ක්‍රමලේඛකයෙකු තම කේත සමහරක් ක්‍රියාත්මක කිරීමේ ප්‍රධාන නූලෙන් වෙනම නූලක් මත ධාවනය කිරීමට තෝරාගෙන එය අවසන් වූ පසු ප්‍රධාන නූලට දැනුම් දෙනු ඇත.

අසින්ක් මූල පදය ඇත්ත වශයෙන්ම කරන්නේ කුමක්ද?

වැනි ක්‍රම නාමයකට අසින්ක් යතුරු පදය උපසර්ග කිරීම

async void DoSomething(){ . . .

අසමමුහුර්ත කාර්යයන් ඇමතීමේදී බලා‍පොරොත්තු යතුරු පදය භාවිතා කිරීමට ක්‍රමලේඛකයාට ඉඩ දෙයි. එපමණයි.

මෙය වැදගත් වන්නේ ඇයි?

බොහෝ මෘදුකාංග පද්ධතිවල ප්‍රධාන නූල් පරිශීලක අතුරුමුහුණතට අදාළ මෙහෙයුම් සඳහා වෙන් කර ඇත. මගේ පරිගණකයේ සම්පූර්ණ කිරීමට තත්පර 5 ක් ගතවන ඉතා සංකීර්ණ පුනරාවර්තන ඇල්ගොරිතමයක් මා ධාවනය කරන්නේ නම්, නමුත් මම මෙය ප්‍රධාන ත්‍රෙඩ් එකේ (යූඅයි නූල්) ධාවනය කරමි. පරිශීලකයා මගේ යෙදුමේ ඕනෑම දෙයක් ක්ලික් කිරීමට උත්සාහ කරන විට, එය ශීත කළ බව පෙනේ මගේ ප්‍රධාන නූල පෝලිම් ගැසී ඇති අතර දැනට බොහෝ මෙහෙයුම් සිදු කරමින් සිටී. එහි ප්‍රති result ලයක් ලෙස බොත්තම ක්ලික් කිරීමෙන් ක්‍රමය ක්‍රියාත්මක කිරීම සඳහා ප්‍රධාන නූලට මූසික ක්ලික් කිරීම සැකසිය නොහැක.

ඔබ අසින්ක් සහ බලා සිටින්න කවදාද?

ඔබ පරිශීලක අතුරුමුහුණතට සම්බන්ධ නොවන කිසිවක් කරන විට අසමමුහුර්ත වචන භාවිතා කරන්න.

එබැවින් ඔබ වැඩසටහනක් ලියන්නේ පරිශීලකයාට ඔවුන්ගේ ජංගම දුරකථනයේ සටහන් කිරීමට ඉඩ දෙන නමුත් සෑම තත්පර 5 කට වරක්ම එය අන්තර්ජාලයේ කාලගුණය පරීක්ෂා කරනු ඇත.

යෙදුමේ පරිශීලකයා ලස්සන පින්තූර ඇඳීම සඳහා ජංගම ස්පර්ශ තිරය සමඟ දිගටම මැදිහත් විය යුතු බැවින් කාලගුණය ලබා ගැනීම සඳහා සෑම තත්පර 5 කට වරක් ජාලයට ඇමතුම් ලබා දෙන තෙක් අපි බලා සිටිය යුතුය.

ඔබ Async සහ Await භාවිතා කරන්නේ කෙසේද?

ඉහත උදාහරණයෙන් පසුව, එය ලියන ආකාරය පිළිබඳ ව්‍යාජ කේත කිහිපයක් මෙන්න:

    //ASYNCHRONOUS
    //this is called using the await keyword every 5 seconds from a polling timer or something.

    async Task CheckWeather()
    {
        var weather = await GetWeather();
        //do something with the weather now you have it
    }

    async Task<WeatherResult> GetWeather()
    {

        var weatherJson = await CallToNetworkAddressToGetWeather();
        return deserializeJson<weatherJson>(weatherJson);
    }

    //SYNCHRONOUS
    //This method is called whenever the screen is pressed
    void ScreenPressed()
    {
        DrawSketchOnScreen();
    }

අමතර සටහන් - යාවත්කාලීන කිරීම

මගේ මුල් සටහන් වල සඳහන් කිරීමට මට අමතක විය C # හි ඔබට බලා සිටිය හැක්කේ කාර්යයන් ඔතා ඇති ක්‍රම පමණි. උදාහරණයක් ලෙස ඔබට මෙම ක්‍රමය බලා සිටිය හැකිය:

// awaiting this will return a string.
// calling this without await (synchronously) will result in a Task<string> object.
async Task<string> FetchHelloWorld() {..

මේ වගේ කාර්යයන් නොවන ක්‍රම ඔබට බලා සිටිය නොහැක:

async string FetchHelloWorld() {..

කාර්ය පන්තිය සඳහා ප්‍රභව කේතය සමාලෝචනය කිරීමට නිදහස් වන්න .


4
මෙය ලිවීමට කාලය ගැනීම ගැන ස්තූතියි.
ප්‍රශාන්ත්

1
එය බුද්ධිමත් සැබෑ ලෝක ප්‍රතිසමයක් විය! සමහර විට සමහර සංවර්ධකයින්ට තාත්වික කාල ප්‍රතිසමයක් සෑදූ විට තාක්ෂණික කොටස් අවබෝධ කර ගැනීම පහසු වේ. ඒ සඳහා ස්තූතියි
කෝඩර් කෙම්ප්

13

මෙම පිළිතුර ASP.NET සඳහා විශේෂිත තොරතුරු සැපයීම අරමුණු කරයි.

එම්වීසී පාලකයේ අසින්ක් / අපේක්ෂාව භාවිතා කිරීමෙන්, නූල් තටාක භාවිතය වැඩි කිරීමට සහ වඩා හොඳ ප්‍රති put ලයක් ලබා ගැනීමට හැකි වනු ඇත, පහත ලිපියේ විස්තර කර ඇති පරිදි,

http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4

ආරම්භයේ දී සමගාමී ඉල්ලීම් විශාල සංඛ්‍යාවක් දකින හෝ පුපුරා ගිය බරක් ඇති වෙබ් යෙදුම්වල (සමගාමී මුදල් හදිසියේම වැඩි වන විට), මෙම වෙබ් සේවා ඇමතුම් අසමමුහුර්ත කිරීම ඔබේ යෙදුමේ ප්‍රතිචාරාත්මක බව වැඩි කරයි. අසමමුහුර්ත ඉල්ලීමක් සමමුහුර්ත ඉල්ලීමක් ලෙස සැකසීමට සමාන කාලයක් ගතවේ. උදාහරණයක් ලෙස, ඉල්ලීමක් සම්පූර්ණ කිරීමට තත්පර දෙකක් අවශ්‍ය වන වෙබ් සේවා ඇමතුමක් ලබා දෙන්නේ නම්, ඉල්ලීම සමමුහුර්තව හෝ අසමමුහුර්තව සිදු කළත් තත්පර දෙකක් ගතවේ. කෙසේ වෙතත්, අසමමුහුර්ත ඇමතුමකදී, පළමු ඉල්ලීම සම්පූර්ණ වන තෙක් බලා සිටින අතරතුර නූල් වෙනත් ඉල්ලීම්වලට ප්‍රතිචාර දැක්වීම අවහිර නොකරයි. එමනිසා, අසමමුහුර්ත ඉල්ලීම් මඟින් දිගු කාලීන මෙහෙයුම් සඳහා සමගාමී ඉල්ලීම් රාශියක් ඇති විට ඉල්ලීම් පෝලිම් සහ නූල් තටාක වර්ධනය වීම වළක්වයි.


11

අසින්ක් / බලා සිටින්න

ඇත්ත වශයෙන්ම අසින්ක් / අවයිට් යනු අසමමුහුර්ත කර්තව්‍යයක් සඳහා නැවත කැඳවීමක් නිර්මාණය කිරීම සඳහා සින්ටැක්ටික් සීනි පමණක් වන පද යුගලයකි.

මෙම ක්‍රියාව උදාහරණයක් ලෙස ගන්න:

    public static void DoSomeWork()
    {
        var task = Task.Run(() =>
        {
            // [RUNS ON WORKER THREAD]

            // IS NOT bubbling up due to the different threads
            throw new Exception();
            Thread.Sleep(2000);

            return "Hello";
        });

        // This is the callback
        task.ContinueWith((t) => {
            // -> Exception is swallowed silently
            Console.WriteLine("Completed");

            // [RUNS ON WORKER THREAD]
        });
    }

ඉහත කේතයට අවාසි කිහිපයක් ඇත. දෝෂ සම්මත වී නැති අතර කියවීමට අපහසුය. නමුත් අසින්ක් සහ බලා සිටින්න අපට උදව් කිරීමට පැමිණේ:

    public async static void DoSomeWork()
    {
        var result = await Task.Run(() =>
        {
            // [RUNS ON WORKER THREAD]

            // IS bubbling up
            throw new Exception();
            Thread.Sleep(2000);

            return "Hello";
        });

        // every thing below is a callback 
        // (including the calling methods)

        Console.WriteLine("Completed");

    }

බලා සිටින්න ඇමතුම් අසින්ක් ක්‍රමවල තිබිය යුතුය. මෙය යම් වාසි ඇත:

  • කාර්යයේ ප්‍රති result ලය ලබා දෙයි
  • ස්වයංක්‍රීයව ඇමතුමක් ලබා දෙයි
  • දෝෂ සඳහා පරික්ෂා කර ඒවාට කෝල්ස්ටැක් එකේ බුබුලු දැමීමට ඉඩ දෙයි (ඇමතුම් ගබඩාවේ කිසිවෙකු බලා නොසිටින ඇමතුම් දක්වා පමණි)
  • ප්රති .ලය එනතෙක් බලා සිටී
  • ප්‍රධාන නූල නිදහස් කරයි
  • ඇමතුම ප්‍රධාන ත්‍රෙඩ් එකේ ධාවනය කරයි
  • කාර්යය සඳහා නූල් පොකුණෙන් සේවක නූල් භාවිතා කරයි
  • කේතය කියවීමට පහසු කරයි
  • සහ තවත් බොහෝ දේ

සටහන : අසින්ක් සහ අවයිට් භාවිතා කරනුයේ මේවා නොකිරීමට අසමමුහුර්ත ඇමතුම් සමඟ ය . Task.Run () වැනි මේ සඳහා ඔබට Task Libary භාවිතා කළ යුතුය.

මෙන්න බලා‍පොරොත්තු වන අතර කිසිවෙකු විසඳුම් බලාපොරොත්තුවෙන් නැත

මෙය කිසිවක් අසමමුහුර්ත විසඳුම නොවේ:

    public static long DoTask()
    {
        stopWatch.Reset();
        stopWatch.Start();

        // [RUNS ON MAIN THREAD]
        var task = Task.Run(() => {
            Thread.Sleep(2000);
            // [RUNS ON WORKER THREAD]
        });
        // goes directly further
        // WITHOUT waiting until the task is finished

        // [RUNS ON MAIN THREAD]

        stopWatch.Stop();
        // 50 milliseconds
        return stopWatch.ElapsedMilliseconds;
    }

මෙය අසයික් ක්‍රමයයි:

    public async static Task<long> DoAwaitTask()
    {
        stopWatch.Reset();
        stopWatch.Start();

        // [RUNS ON MAIN THREAD]

        await Task.Run(() => {
            Thread.Sleep(2000);
            // [RUNS ON WORKER THREAD]
        });
        // Waits until task is finished

        // [RUNS ON MAIN THREAD]

        stopWatch.Stop();
        // 2050 milliseconds
        return stopWatch.ElapsedMilliseconds;
    }

බලා සිටීමේ මූල පදය නොමැතිව ඔබට සැබවින්ම අසින්ක් ක්‍රමයක් ඇමතිය හැකි නමුත් මෙයින් අදහස් කරන්නේ මෙහි ඇති ඕනෑම ව්‍යතිරේකයක් මුදා හැරීමේ මාදිලියේ ගිල දමා ඇති බවයි:

    public static Stopwatch stopWatch { get; } = new Stopwatch();

    static void Main(string[] args)
    {
        Console.WriteLine("DoAwaitTask: " + DoAwaitTask().Result + " ms");
        // 2050 (2000 more because of the await)
        Console.WriteLine("DoTask: " + DoTask() + " ms");
        // 50
        Console.ReadKey();
    }

අසින්ක් සහ අවයිට් සමාන්තර පරිගණනය සඳහා අදහස් නොකෙරේ. ඔබේ ප්‍රධාන නූල අවහිර නොකිරීමට ඒවා භාවිතා වේ. එය asp.net හෝ Windows යෙදුම් ගැන වන විට, ජාල ඇමතුමක් හේතුවෙන් ඔබේ ප්‍රධාන නූල අවහිර කිරීම නරක දෙයකි. ඔබ මෙය කරන්නේ නම්, ඔබගේ යෙදුම ප්‍රතිචාර නොදක්වන හෝ බිඳ වැටෙනු ඇත.

තවත් උදාහරණ සඳහා ms docs බලන්න .


10

ඇත්තම කිව්වොත් මම හිතන්නේ හොඳම පැහැදිලි කිරීම අනාගතය ගැන සහ විකිපීඩියාවේ පොරොන්දු: http://en.wikipedia.org/wiki/Futures_and_promises

මූලික අදහස නම්, කාර්යයන් අසමමුහුර්තව ක්‍රියාත්මක කරන වෙනම නූල් සංචිතයක් ඔබ සතුව තිබීමයි. එය භාවිතා කරන විට. කෙසේ වෙතත් වස්තුව එය යම් වේලාවක මෙහෙයුම ක්‍රියාත්මක කරන බවට පොරොන්දු වන අතර ඔබ ඉල්ලූ විට ප්‍රති result ලය ලබා දෙයි. මෙයින් අදහස් කරන්නේ ඔබ ප්‍රති result ලය ඉල්ලා සිටින විට එය අවහිර වන අතර එය අවසන් වී නැති නමුත් නූල් තටාකයේ වෙනත් ආකාරයකින් ක්‍රියාත්මක කරන්න.

එතැන් සිට ඔබට දේවල් ප්‍රශස්තිකරණය කළ හැකිය: සමහර මෙහෙයුම් අසමමුහුර්තව ක්‍රියාත්මක කළ හැකි අතර, පසුකාලීන ඉල්ලීම් එකට එකතු කර / හෝ ඒවා නැවත සකස් කිරීමෙන් ඔබට ගොනු IO සහ ජාල සන්නිවේදනය වැනි දේ ප්‍රශස්තිකරණය කළ හැකිය. මෙය දැනටමත් මයික්‍රොසොෆ්ට් හි කාර්ය රාමුව තුළ තිබේදැයි මට විශ්වාස නැත - නමුත් එය එසේ නොවේ නම් මම එකතු කරන පළමු දේවලින් එකක් වනු ඇත.

C # 4.0 හි අස්වැන්න සමඟ අනාගත රටාව වර්ග කිරීම ඔබට සැබවින්ම ක්‍රියාත්මක කළ හැකිය. එය හරියටම ක්‍රියාත්මක වන්නේ කෙසේදැයි දැන ගැනීමට ඔබට අවශ්‍ය නම්, හොඳ රැකියාවක් කරන මෙම සබැඳිය මට නිර්දේශ කළ හැකිය: http://code.google.com/p/fracture/source/browse/trunk/Squared/TaskLib/ . කෙසේ වෙතත්, ඔබ එය තනිවම සෙල්ලම් කිරීමට පටන් ගන්නේ නම්, ඔබට සියලු සිසිල් දේවල් කිරීමට අවශ්‍ය නම් ඔබට ඇත්ත වශයෙන්ම භාෂා සහාය අවශ්‍ය බව ඔබට පෙනෙනු ඇත - මයික්‍රොසොෆ්ට් කළේ හරියටම එයයි.


9

මෙම බලන්න වීණාවක් https://dotnetfiddle.net/VhZdLU ක්රියාත්මක වන සඳහා (සහ හැකි නම් එය වැඩි දියුණු) සරල කොන්සෝලය අයදුම් යාමත් සමග පෙන්වයි කාර්ය, Task.WaitAll (), අසමකාලීක හා ඉදිරියේදී බලාපොරොත්තු වන්න එම වැඩසටහන මෙහෙයවන.

මෙම ප්‍රහේලිකාව මඟින් ඔබේ ක්‍රියාත්මක කිරීමේ චක්‍රීය සංකල්පය ඉවත් කළ යුතුය.

මෙන්න නියැදි කේතය

using System;
using System.Threading.Tasks;

public class Program
{
    public static void Main()
    {               
        var a = MyMethodAsync(); //Task started for Execution and immediately goes to Line 19 of the code. Cursor will come back as soon as await operator is met       
        Console.WriteLine("Cursor Moved to Next Line Without Waiting for MyMethodAsync() completion");
        Console.WriteLine("Now Waiting for Task to be Finished");       
        Task.WaitAll(a); //Now Waiting      
        Console.WriteLine("Exiting CommandLine");       
    }

    public static async Task MyMethodAsync()
    {
        Task<int> longRunningTask = LongRunningOperation();
        // independent work which doesn't need the result of LongRunningOperationAsync can be done here
        Console.WriteLine("Independent Works of now executes in MyMethodAsync()");
        //and now we call await on the task 
        int result = await longRunningTask;
        //use the result 
        Console.WriteLine("Result of LongRunningOperation() is " + result);
    }

    public static async Task<int> LongRunningOperation() // assume we return an int from this long running operation 
    {
        Console.WriteLine("LongRunningOperation() Started");
        await Task.Delay(2000); // 2 second delay
        Console.WriteLine("LongRunningOperation() Finished after 2 Seconds");
        return 1;
    }   

}

නිමැවුම් කවුළුවෙන් එන හෝඩුවාව: රූප විස්තරය මෙහි ඇතුළත් කරන්න


3

මා එය තේරුම් ගන්නා ආකාරය ද, මිශ්‍රණයට තුන්වන වාරයක් එකතු කළ යුතුය : Task.

Async එය අසමමුහුර්ත ක්‍රමයක් යැයි කීමට ඔබ ඔබේ ක්‍රමයට ඇතුළත් කළ සුදුසුකම්කරුවෙකි.

Task යනු නැවත පැමිණීමයි async ශ්‍රිතයේ . එය අසමමුහුර්තව ක්‍රියාත්මක කරයි.

ඔබ awaitකාර්යයක්. කේත ක්‍රියාත්මක කිරීම මෙම රේඛාවට ළඟා වූ විට, පාලනය ඔබගේ අවට ඇති මුල් ශ්‍රිතය අමතන්නා වෙත ආපසු යයි.

ඒ වෙනුවට නම්, ඔබ නැවත පැවරීම asyncකාර්යය (එනම් Taskවිචල්ය කිරීමට), කේතය ක්රියාත්මක මෙම දුම්රිය මාර්ගය වූ විට, එය දිගටම එම රේඛාව පසුගිය අවට උත්සවයට අතර එම Taskඅසම්මිතික ඉටු.


3
public static void Main(string[] args)
{
    string result = DownloadContentAsync().Result;
    Console.ReadKey();
}

// You use the async keyword to mark a method for asynchronous operations.
// The "async" modifier simply starts synchronously the current thread. 
// What it does is enable the method to be split into multiple pieces.
// The boundaries of these pieces are marked with the await keyword.
public static async Task<string> DownloadContentAsync()// By convention, the method name ends with "Async
{
    using (HttpClient client = new HttpClient())
    {
        // When you use the await keyword, the compiler generates the code that checks if the asynchronous operation is finished.
        // If it is already finished, the method continues to run synchronously.
        // If not completed, the state machine will connect a continuation method that must be executed WHEN the Task is completed.


        // Http request example. 
        // (In this example I can set the milliseconds after "sleep=")
        String result = await client.GetStringAsync("http://httpstat.us/200?sleep=1000");

        Console.WriteLine(result);

        // After completing the result response, the state machine will continue to synchronously execute the other processes.


        return result;
    }
}

3

ඉහළ මට්ටමක:

1) අසින්ක් යතුරුපදය මඟින් බලා සිටීම සක්‍රීය කරන අතර එපමණයි. අසින්ක් යතුරුපදය වෙනම ත්‍රෙඩ් එකක ක්‍රමය ක්‍රියාත්මක නොකරයි. ආරම්භක f අසින්ක් ක්‍රමය කාලය ගතවන කාර්යයක් බලාපොරොත්තුවෙන් සිටින තෙක් සමමුහුර්තව ක්‍රියාත්මක වේ.

2) ටී වර්ගයේ කාර්යය හෝ කාර්යය නැවත ලබා දෙන ක්‍රමයක් පිළිබඳව ඔබට බලා සිටිය හැකිය. ඔබට අසින්ක් අවලංගු කිරීමේ ක්‍රමයක් බලා සිටිය නොහැක.

3) ප්‍රධාන නූල් හමු වන මොහොතේ කාලය ගතවන කාර්යය හෝ සැබෑ වැඩ ආරම්භ කරන විට බලා සිටින විට, ප්‍රධාන නූල් වත්මන් ක්‍රමයේ අමතන්නා වෙත නැවත පැමිණේ.

4) ප්‍රධාන ත්‍රෙඩ් එක තවමත් ක්‍රියාත්මක වන කාර්යයක් සඳහා බලා සිටින බව පෙනේ නම්, එය ඒ සඳහා බලා නොසිට වත්මන් ක්‍රමවේදය අමතන්නා වෙත නැවත පැමිණේ. මේ ආකාරයෙන්, යෙදුම ප්රතිචාරාත්මකව පවතී.

5) සැකසුම් කාර්යය සඳහා බලා සිටින්න, දැන් නූල් සංචිතයෙන් වෙනම නූල් මත ක්‍රියාත්මක වේ.

6) මෙම අපේක්ෂිත කාර්යය අවසන් වූ විට, ඊට පහළින් ඇති සියලුම කේත වෙනම නූල් මඟින් ක්‍රියාත්මක වේ

පහත දැක්වෙන්නේ නියැදි කේතයයි. එය ක්‍රියාත්මක කර නූල් හැඳුනුම්පත පරීක්ෂා කරන්න

using System;
using System.Threading;
using System.Threading.Tasks;

namespace AsyncAwaitDemo
{
    class Program
    {
        public static async void AsynchronousOperation()
        {
            Console.WriteLine("Inside AsynchronousOperation Before AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
            //Task<int> _task = AsyncMethod();
            int count = await AsyncMethod();

            Console.WriteLine("Inside AsynchronousOperation After AsyncMethod Before Await, Thread Id: " + Thread.CurrentThread.ManagedThreadId);

            //int count = await _task;

            Console.WriteLine("Inside AsynchronousOperation After AsyncMethod After Await Before DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);

            DependentMethod(count);

            Console.WriteLine("Inside AsynchronousOperation After AsyncMethod After Await After DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
        }

        public static async Task<int> AsyncMethod()
        {
            Console.WriteLine("Inside AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
            int count = 0;

            await Task.Run(() =>
            {
                Console.WriteLine("Executing a long running task which takes 10 seconds to complete, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(20000);
                count = 10;
            });

            Console.WriteLine("Completed AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);

            return count;
        }       

        public static void DependentMethod(int count)
        {
            Console.WriteLine("Inside DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId + ". Total count is " + count);
        }

        static void Main(string[] args)
        {
            Console.WriteLine("Started Main method, Thread Id: " + Thread.CurrentThread.ManagedThreadId);

            AsynchronousOperation();

            Console.WriteLine("Completed Main method, Thread Id: " + Thread.CurrentThread.ManagedThreadId);

            Console.ReadKey();
        }

    }
}

2

පහත කේතයේ, HttpClient ක්‍රමය GetByteArrayAsync මඟින් කාර්යයක් ලබා දෙයි, getContentsTask. කාර්යය සම්පූර්ණ වූ විට සත්‍ය බයිට් අරා නිපදවීමට පොරොන්දුවකි. GetContentsTask සම්පුර්ණ වන තුරු SumPageSizesAsync හි ක්‍රියාත්මක කිරීම අත්හිටුවීම සඳහා getContentsTask වෙත බලා සිටින ක්‍රියාකරු යොදනු ලැබේ. මේ අතර, පාලනය SumPageSizesAsync අමතන්නා වෙත යවනු ලැබේ. GetContentsTask අවසන් වූ විට, පොරොත්තු ප්‍රකාශනය බයිට් අරාවකට ඇගයීමට ලක් කරයි.

private async Task SumPageSizesAsync()
{
    // To use the HttpClient type in desktop apps, you must include a using directive and add a 
    // reference for the System.Net.Http namespace.
    HttpClient client = new HttpClient();
    // . . .
    Task<byte[]> getContentsTask = client.GetByteArrayAsync(url);
    byte[] urlContents = await getContentsTask;

    // Equivalently, now that you see how it works, you can write the same thing in a single line.
    //byte[] urlContents = await client.GetByteArrayAsync(url);
    // . . .
}

1

දිගු කාලීන තර්කනය සිදු කිරීම සඳහා ඒවා භාවිතා කිරීම පසුබිම් නූල් වලට සමානද?

මෙම ලිපිය MDSN: අසමමුහුර්ත ක්‍රමලේඛනය අසින්ක් සහ බලා සිටින්න (සී #) එය පැහැදිලිව පැහැදිලි කරයි:

අසින්ක් සහ අපේක්ෂිත මූල පද අතිරේක නූල් සෑදීමට හේතු නොවේ. අසින්ක් ක්‍රමයට බහු නූල් අවශ්‍ය නොවේ. මෙම ක්‍රමය වත්මන් සමමුහුර්තකරණ සන්දර්භය මත ක්‍රියාත්මක වන අතර නූල් මත කාලය භාවිතා කරන්නේ ක්‍රමය සක්‍රිය වූ විට පමණි.


1

පහත දැක්වෙන්නේ සංවාදය විවෘත කිරීමෙන් එක්සෙල් ගොනුව කියවන අතර පසුව අසමමුහුර්ත භාවිතා කර එක්සෙල් සිට එක පේළියක් කියවා ජාලයට බැඳ තබන කේතය අසමමුහුර්තව ධාවනය කිරීමට බලා සිටීමයි.

namespace EmailBillingRates
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            lblProcessing.Text = "";
        }

        private async void btnReadExcel_Click(object sender, EventArgs e)
        {
            string filename = OpenFileDialog();

            Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
            Microsoft.Office.Interop.Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(filename);
            Microsoft.Office.Interop.Excel._Worksheet xlWorksheet = xlWorkbook.Sheets[1];
            Microsoft.Office.Interop.Excel.Range xlRange = xlWorksheet.UsedRange;
            try
            {
                Task<int> longRunningTask = BindGrid(xlRange);
                int result = await longRunningTask;

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
            finally
            {
                //cleanup  
               // GC.Collect();
                //GC.WaitForPendingFinalizers();

                //rule of thumb for releasing com objects:  
                //  never use two dots, all COM objects must be referenced and released individually  
                //  ex: [somthing].[something].[something] is bad  

                //release com objects to fully kill excel process from running in the background  
                Marshal.ReleaseComObject(xlRange);
                Marshal.ReleaseComObject(xlWorksheet);

                //close and release  
                xlWorkbook.Close();
                Marshal.ReleaseComObject(xlWorkbook);

                //quit and release  
                xlApp.Quit();
                Marshal.ReleaseComObject(xlApp);
            }

        }

        private void btnSendEmail_Click(object sender, EventArgs e)
        {

        }

        private string OpenFileDialog()
        {
            string filename = "";
            OpenFileDialog fdlg = new OpenFileDialog();
            fdlg.Title = "Excel File Dialog";
            fdlg.InitialDirectory = @"c:\";
            fdlg.Filter = "All files (*.*)|*.*|All files (*.*)|*.*";
            fdlg.FilterIndex = 2;
            fdlg.RestoreDirectory = true;
            if (fdlg.ShowDialog() == DialogResult.OK)
            {
                filename = fdlg.FileName;
            }
            return filename;
        }

        private async Task<int> BindGrid(Microsoft.Office.Interop.Excel.Range xlRange)
        {
            lblProcessing.Text = "Processing File.. Please wait";
            int rowCount = xlRange.Rows.Count;
            int colCount = xlRange.Columns.Count;

            // dt.Column = colCount;  
            dataGridView1.ColumnCount = colCount;
            dataGridView1.RowCount = rowCount;

            for (int i = 1; i <= rowCount; i++)
            {
                for (int j = 1; j <= colCount; j++)
                {
                    //write the value to the Grid  
                    if (xlRange.Cells[i, j] != null && xlRange.Cells[i, j].Value2 != null)
                    {
                         await Task.Delay(1);
                         dataGridView1.Rows[i - 1].Cells[j - 1].Value =  xlRange.Cells[i, j].Value2.ToString();
                    }

                }
            }
            lblProcessing.Text = "";
            return 0;
        }
    }

    internal class async
    {
    }
}

0

බලා සිටීම / අසංක වීම පිළිබඳ සාමාන්‍ය මග පෙන්වීමක් ලෙස මෙහි පිළිතුරු ප්‍රයෝජනවත් වේ. රැඳවුම් / අසින්ක් වයර් කරන්නේ කෙසේද යන්න පිළිබඳ විස්තරයක් ද ඒවායේ අඩංගු වේ. මෙම සැලසුම් රටාව භාවිතා කිරීමට පෙර ඔබ දැනගත යුතු ප්‍රායෝගික අත්දැකීම් ඔබ සමඟ බෙදා ගැනීමට මම කැමතියි.

"බලා සිටින්න" යන වචනය වචනානුසාරයෙන් වේ, එබැවින් ඔබ එය කැඳවන ඕනෑම නූලක් ඉදිරියට යාමට පෙර ක්‍රමයේ ප්‍රති result ලය එනතෙක් බලා සිටී. මත පෙරට ආ නූල්, මේ වනාහි ආපදා . දර්ශන, දර්ශන ආකෘති, ආරම්භක සජීවිකරණ සහ එම මූලද්‍රව්‍ය සමඟ ඔබ ඇරඹූ වෙනත් ඕනෑම දෙයක් ඇතුළුව ඔබේ යෙදුම තැනීමේ බර පෙරබිම් නූල් මගින් දරයි. එබැවින් ඔබ පෙරබිම් නූල් බලාපොරොත්තුවෙන් සිටින විට, ඔබ යෙදුම නවත්වයි . කිසිවක් සිදු නොවන බව පෙනෙන විට පරිශීලකයා බලා සිටී. මෙය user ණාත්මක පරිශීලක අත්දැකීමක් සපයයි.

විවිධ ක්‍රම භාවිතා කරමින් ඔබට පසුබිම් නූලක් බලා සිටිය හැකිය:

Device.BeginInvokeOnMainThread(async () => { await AnyAwaitableMethod(); });

// Notice that we do not await the following call, 
// as that would tie it to the foreground thread.
try
{
Task.Run(async () => { await AnyAwaitableMethod(); });
}
catch
{}

මෙම ප්‍රකාශ සඳහා සම්පූර්ණ කේතය https://github.com/marcusts/xamarin-forms-annoyances හි ඇත. AwaitAsyncAntipattern.sln නමින් විසඳුම බලන්න.

GitHub වෙබ් අඩවිය මෙම මාතෘකාව පිළිබඳ වඩාත් සවිස්තරාත්මක සාකච්ඡාවකට සබැඳි ද සපයයි.


1
මා තේරුම් ගත් පරිදි, async / awaitකෝල්බැක් සඳහා සින්ටැක්ටික් සීනි, එයට නූල් දැමීම සමග කිසිදු සම්බන්ධයක් නැත. msdn.microsoft.com/en-us/magazine/hh456401.aspx එය CPU නොවන බැඳී ඇති කේත සඳහා වන අතර, උදා: ආදානය හෝ ප්‍රමාදයක් බලා සිටීම. Task.RunCPU- බන්ධන කේතය සඳහා පමණක් භාවිතා කළ යුතුය blog.stephencleary.com/2013/10/…
ජ්‍යාමිතික

The term "await" is literal, so whatever thread you call it on will wait for the result of the method before continuing.මෙය සත්‍ය නොවේ - සමහර විට ඔබ අදහස් කළේ Task.Wait () ද? ඔබ භාවිතා කරන විට await, එය ඔබ බලා සිටින ඕනෑම දෙයක් සම්පූර්ණ වූ විට ක්‍රියාත්මක කළ යුතු අඛණ්ඩ ක්‍රමයක් ලෙස ඉතිරි ක්‍රමය සකසයි. එය ඔබ භාවිතා කළ ක්‍රමයෙන් පිටවන බැවින් ඇමතුම්කරුට ඉදිරියට යා හැකිය. එවිට පොරොත්තු රේඛාව සැබවින්ම සම්පුර්ණ වූ විට, එය එම ක්‍රමයේ ඉතිරි කොටස සමහර නූල් වලින් (සාමාන්‍යයෙන් සේවක නූල්) අවසන් කරයි.
දොන් චෙඩ්ල්

coregeometrikal async/awaitයනු හරය .NET Threads නිදහස් කිරීමයි . ඔබ awaitසැබවින්ම අසමමුහුර්ත මෙහෙයුමක යෙදෙන විට (.NET හි File.WriteAsync වැනි), එය ඔබ භාවිතා කළ ක්‍රමයේ ඉතිරි කොටස අත්හිටුවයි await, එවිට අමතන්නාට ඉදිරියට යා හැකි අතර එහි අරමුණ අවසන් කළ හැකිය. නූල් අවහිර කිරීමක් හෝ await-ed මෙහෙයුම සඳහා බලා සිටීම නොමැත . ඔබ awaitසංස්කරණය කළ මෙහෙයුම සම්පුර්ණ වූ විට, ක්‍රමයේ ඉතිරි කොටස async/awaitනූල් මත තබා ක්‍රියාත්මක කරනු ලැබේ (ඇමතුම් ආපසු ලබා ගැනීමේ අදහසකට සමානය).
දොන් චෙඩ්ල්

-1

ඔබ ක්‍රියාත්මක වන නූල් ගණන පාලනය කිරීමට කාර්යයන් ඔබට ඉඩ දෙයි.
නූල්වල ප්‍රශස්ත සංඛ්‍යාව යනු ඔබ සතුව ඇති මධ්‍ය ගණනයි.

  • ඔබගේ යෙදුම කොන්සෝලය, වින් ෆෝම්ස් හෝ ඩබ්ලිව්පීඑෆ් වන විට ඔබ සාමාන්‍යයෙන් තනි නූල් මත ධාවනය වේ.

    • මෙම අවස්ථාවේදී ඔබට නූල් ගණන වැඩි කිරීමට අවශ්‍යය
    • ඔබේ ප්‍රධාන මෙවලම Task.Run()සහ සමහර විට Parallel.ForERach()
    • (Task.Run () සමඟ) නූල් එකක සමමුහුර්ත I / O කිරීම උප ප්‍රශස්ත නමුත් පිළිගත හැකි ය
  • ඔබගේ යෙදුම වෙබ්සර්වරයක ක්‍රියාත්මක වන විට එය සාමාන්‍යයෙන් බොහෝ නූල් මත ධාවනය වේ.
    asp.net පැමිණෙන ඉල්ලීම් සඳහා බලා සිටින අතර සෑම කෙනෙකුම ඉක්මනින් නව තටාකයකට භාර දෙයි.

    • මෙම අවස්ථාවේදී ඔබට නූල් ගණන අඩු කිරීමට අවශ්‍යය
    • ඔබේ ප්‍රධාන මෙවලම වන්නේ awaitඅසමමුහුර්ත I / O.
    • ඔබේ අසින්ක් ක්‍රියාකාරී ක්‍රමයේ සිට සත්‍ය I / O දක්වා නොබිඳිය හැකි පොරොත්තු දාමයක් ඇති බවට වග බලා ගන්න
    • (Task.Run () සමඟ) නූල් එකක සමමුහුර්ත I / O හෝ CPU තීව්‍ර වැඩ කිරීම අක්‍රීය කිරීමකි.

1
කාර්යයන් සහ නූල් සහසම්බන්ධ කිරීම IMHO හි අසින්ක්-අපේක්ෂිත සංකල්පය පැහැදිලි කිරීම ආරම්භ කිරීම වැරදි ක්‍රමයකි. එය ඔබට පසුව ඉගෙන ගැනීමට අවශ්‍ය වන ආකාරයේ පැහැදිලි කිරීමකි.
තියඩෝර් සූලියස්

Od තියඩෝර්සූලියාස්, මම එකඟ නොවෙමි. අසින්ක් අයි / ඕ හි සමස්ත අරමුණ කුමක්දැයි ඔබ සිතන්නේ කුමක්ද? මම හිතන්නේ එය නූල් නිදහස් කිරීම ගැන ය. Task.Run () හොඳ හෝ නරක අදහසක් දැයි දැන ගැනීමට පෙර ඔබ සතුව නූල් කීයක් තිබේදැයි දැනගත යුතුය.
හෙන්ක් හෝල්ටර්මන්
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.