ऐसा इसलिए है क्योंकि async
और await
कीवर्ड coroutines नामक किसी चीज़ के लिए सिंटैक्टिकल चीनी हैं।
एसिंक्रोनस विधियों के निर्माण का समर्थन करने के लिए कोई विशेष आईएल निर्देश नहीं हैं। इसके बजाए, एक एसिंक विधि किसी भी तरह की राज्य मशीन के रूप में देखी जा सकती है।
मैं इस उदाहरण के रूप में संभव के रूप में कम करने की कोशिश करेंगे:
[TestClass]
public class AsyncTest
{
[TestMethod]
public async Task RunTest_1()
{
var result = await GetStringAsync();
Console.WriteLine(result);
}
private async Task AppendLineAsync(StringBuilder builder, string text)
{
await Task.Delay(1000);
builder.AppendLine(text);
}
public async Task<string> GetStringAsync()
{
// Code before first await
var builder = new StringBuilder();
var secondLine = "Second Line";
// First await
await AppendLineAsync(builder, "First Line");
// Inner synchronous code
builder.AppendLine(secondLine);
// Second await
await AppendLineAsync(builder, "Third Line");
// Return
return builder.ToString();
}
}
यह जैसा कि आप शायद करने के लिए इस्तेमाल हो गए कुछ async कोड है: पहली बार में हमारी GetStringAsync
विधि तुल्यकालिक एक StringBuilder
बनाता है, तो यह इंतजार कर रहा है कुछ असीमित तरीकों और अंत में यह परिणाम देता है। await
कीवर्ड नहीं होने पर यह कैसे लागू किया जाएगा?
AsyncTest
वर्ग के लिए निम्न कोड जोड़ें:
[TestMethod]
public async Task RunTest_2()
{
var result = await GetStringAsyncWithoutAwait();
Console.WriteLine(result);
}
public Task<string> GetStringAsyncWithoutAwait()
{
// Code before first await
var builder = new StringBuilder();
var secondLine = "Second Line";
return new StateMachine(this, builder, secondLine).CreateTask();
}
private class StateMachine
{
private readonly AsyncTest instance;
private readonly StringBuilder builder;
private readonly string secondLine;
private readonly TaskCompletionSource<string> completionSource;
private int state = 0;
public StateMachine(AsyncTest instance, StringBuilder builder, string secondLine)
{
this.instance = instance;
this.builder = builder;
this.secondLine = secondLine;
this.completionSource = new TaskCompletionSource<string>();
}
public Task<string> CreateTask()
{
DoWork();
return this.completionSource.Task;
}
private void DoWork()
{
switch (this.state)
{
case 0:
goto state_0;
case 1:
goto state_1;
case 2:
goto state_2;
}
state_0:
this.state = 1;
// First await
var firstAwaiter = this.instance.AppendLineAsync(builder, "First Line")
.GetAwaiter();
firstAwaiter.OnCompleted(DoWork);
return;
state_1:
this.state = 2;
// Inner synchronous code
this.builder.AppendLine(this.secondLine);
// Second await
var secondAwaiter = this.instance.AppendLineAsync(builder, "Third Line")
.GetAwaiter();
secondAwaiter.OnCompleted(DoWork);
return;
state_2:
// Return
var result = this.builder.ToString();
this.completionSource.SetResult(result);
}
}
तो स्पष्ट रूप से पहले await
कीवर्ड से पहले कोड सिर्फ एक ही रहता है। बाकी सब कुछ एक राज्य मशीन में परिवर्तित हो जाता है जो आपके पिछले कोड को टुकड़े टुकड़े करने के लिए goto
कथन का उपयोग करता है। हर बार प्रतीक्षा किए गए कार्यों में से एक पूरा हो जाता है, राज्य मशीन अगले चरण में आगे बढ़ती है।
यह उदाहरण स्पष्ट करने के लिए अतिसंवेदनशील है कि दृश्यों के पीछे क्या होता है। त्रुटि प्रबंधन और कुछ foreach
जोड़ें- आपकी एसिंक विधि में लूप, और राज्य मशीन अधिक जटिल हो जाती है।
वैसे, सी # में एक और निर्माण है जो ऐसी चीज करता है: yield
कीवर्ड। यह एक राज्य मशीन भी उत्पन्न करता है और कोड await
उत्पादन के समान दिखता है।
आगे पढ़ने के लिए, this CodeProject पर देखें जो उत्पन्न राज्य मशीन में गहराई से दिखता है।
async/await में कोड [जेफ रिचटर के असिंक एन्युमेरेटर पैटर्न] पर आधारित है (http://channel9.msdn.com/Blogs/Charles/Jeffrey-Richter-and-his-AsyncEnumerator)। इस https://ndepend.uservoice.com/forums/226344- निर्भर-user-voice/suggestions/6375659-exclude-compiler-generated-code-by-default के लिए एक फिक्स का सुझाव देने वाली आवाज़ पहले से ही है। – Aron
क्योंकि इस तरह async/await काम करता है। आप जो देखते हैं वह [कार्यान्वयन विस्तार] (http://msdn.microsoft.com/en-us/magazine/hh456402.aspx) सुविधा का है। –
यह वास्तव में यह सुनिश्चित करने के महत्व को रेखांकित करता है कि जब आप इसकी आवश्यकता नहीं होती है तो आप अंधेरे से सभी जगहों पर एसिंक का उपयोग नहीं कर रहे हैं। मुझे लगता है कि मुझे उम्मीद थी कि यह अपेक्षाकृत अधिक है। –