यह बहुत देर हो सकती है लेकिन यह उपयोगी जांच हो सकती है:
संकलित कोड ( IL ) की आंतरिक संरचना के बारे में है :
public static async Task<int> GetTestData()
{
return 12;
}
यह IL में हो जाता है:
.method private hidebysig static class [mscorlib]System.Threading.Tasks.Task`1<int32>
GetTestData() cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.AsyncStateMachineAttribute::.ctor(class [mscorlib]System.Type) = ( 01 00 28 55 73 61 67 65 4C 69 62 72 61 72 79 2E
53 74 61 72 74 54 79 70 65 2B 3C 47 65 74 54 65
73 74 44 61 74 61 3E 64 5F 5F 31 00 00 )
.custom instance void [mscorlib]System.Diagnostics.DebuggerStepThroughAttribute::.ctor() = ( 01 00 00 00 )
.maxstack 2
.locals init ([0] class UsageLibrary.StartType/'<GetTestData>d__1' V_0,
[1] valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<int32> V_1)
IL_0000: newobj instance void UsageLibrary.StartType/'<GetTestData>d__1'::.ctor()
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: call valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<!0> valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<int32>::Create()
IL_000c: stfld valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<int32> UsageLibrary.StartType/'<GetTestData>d__1'::'<>t__builder'
IL_0011: ldloc.0
IL_0012: ldc.i4.m1
IL_0013: stfld int32 UsageLibrary.StartType/'<GetTestData>d__1'::'<>1__state'
IL_0018: ldloc.0
IL_0019: ldfld valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<int32> UsageLibrary.StartType/'<GetTestData>d__1'::'<>t__builder'
IL_001e: stloc.1
IL_001f: ldloca.s V_1
IL_0021: ldloca.s V_0
IL_0023: call instance void valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<int32>::Start<class UsageLibrary.StartType/'<GetTestData>d__1'>(!!0&)
IL_0028: ldloc.0
IL_0029: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<int32> UsageLibrary.StartType/'<GetTestData>d__1'::'<>t__builder'
IL_002e: call instance class [mscorlib]System.Threading.Tasks.Task`1<!0> valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<int32>::get_Task()
IL_0033: ret
}
और async और कार्य विधि के बिना:
public static int GetTestData()
{
return 12;
}
बन जाता है:
.method private hidebysig static int32 GetTestData() cil managed
{
.maxstack 1
.locals init ([0] int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.s 12
IL_0003: stloc.0
IL_0004: br.s IL_0006
IL_0006: ldloc.0
IL_0007: ret
}
जैसा कि आप इन तरीकों के बीच बड़ा अंतर देख सकते हैं। यदि आप async विधि के अंदर प्रतीक्षा का उपयोग नहीं करते हैं और async विधि (उदाहरण के लिए API कॉल या ईवेंट हैंडलर) का उपयोग करने के बारे में परवाह नहीं करते हैं, तो अच्छा विचार इसे सामान्य सिंक विधि में बदल देगा (यह आपके एप्लिकेशन प्रदर्शन को बचाता है)।
अपडेट किया गया:
Microsoft डॉक्स https://docs.microsoft.com/en-us/dotnet/standard/async-in-depth से अतिरिक्त जानकारी भी है :
async विधियों के लिए उनके शरीर में एक प्रतीक्षित खोजशब्द की आवश्यकता है या वे कभी उपज नहीं देंगे! यह ध्यान रखना जरूरी है। यदि एसिटिक विधि के शरीर में वाट्स का उपयोग नहीं किया जाता है, तो सी # कंपाइलर एक चेतावनी उत्पन्न करेगा, लेकिन कोड एक सामान्य विधि के रूप में संकलित और चलेगा। ध्यान दें कि यह भी अविश्वसनीय रूप से अक्षम होगा, क्योंकि एसिंक्स विधि के लिए सी # संकलक द्वारा उत्पन्न राज्य मशीन कुछ भी पूरा नहीं करेगी।
async
?