खोज…


एस्सेक्स / प्रतीक्षित कीवर्ड के लिए छद्मकोड

एक सरल अतुल्यकालिक विधि पर विचार करें:

async Task Foo()
{
    Bar();
    await Baz();
    Qux();
}

सरल करते हुए, हम कह सकते हैं कि इस कोड का वास्तव में मतलब निम्न है:

Task Foo()
{
    Bar();
    Task t = Baz();
    var context = SynchronizationContext.Current;
    t.ContinueWith(task) =>
    {
        if (context == null)
            Qux();
        else
            context.Post((obj) => Qux(), null);
    }, TaskScheduler.Current);

    return t;
}

इसका मतलब यह है कि अगर यह मौजूद है तो async / await खोजशब्द वर्तमान तुल्यकालन संदर्भ का उपयोग करते हैं। यानी आप लाइब्रेरी कोड लिख सकते हैं जो UI, वेब और कंसोल एप्लिकेशन में सही तरीके से काम करेगा।

स्रोत लेख

सिंक्रनाइज़ेशन संदर्भ को अक्षम करना

सिंक्रोनाइज़ेशन संदर्भ को अक्षम करने के लिए आपको ConfigureAwait विधि को कॉल करना चाहिए:

async Task() Foo()
{
    await Task.Run(() => Console.WriteLine("Test"));
}

. . .

Foo().ConfigureAwait(false);

ConfigureAwait डिफ़ॉल्ट SynchronizationContext कैप्चरिंग व्यवहार से बचने के लिए एक साधन प्रदान करता है; फ़्लोऑनटेक्स्ट पैरामीटर के लिए गलत तरीके से पास होने से, सिंक्रोनाइज़ेशन कॉनटेक्स्ट को प्रतीक्षा के बाद निष्पादन को फिर से शुरू करने के लिए उपयोग करने से रोकता है।

उद्धरण यह सब के बारे में सिंक्रोनाइज़ेशन कॉन्टेक्स्ट है

क्यों SynchronizationContext इतना महत्वपूर्ण है?

इस उदाहरण पर विचार करें:

private void button1_Click(object sender, EventArgs e)
{
    label1.Text = RunTooLong();
}

जब तक RunTooLong पूरा नहीं होगा, तब तक यह विधि UI एप्लिकेशन को फ्रीज कर RunTooLong । आवेदन अनुत्तरदायी होगा।

आप आंतरिक कोड को अतुल्यकालिक रूप से चलाने का प्रयास कर सकते हैं:

private void button1_Click(object sender, EventArgs e)
{
    Task.Run(() => label1.Text = RunTooLong());
}

लेकिन यह कोड निष्पादित नहीं करेगा क्योंकि आंतरिक निकाय को गैर-UI थ्रेड पर चलाया जा सकता है और इसमें UI गुणों को सीधे नहीं बदलना चाहिए :

private void button1_Click(object sender, EventArgs e)
{
    Task.Run(() =>
    {
        var label1Text = RunTooLong();

        if (label1.InvokeRequired)
            lable1.BeginInvoke((Action) delegate() { label1.Text = label1Text; });
        else
            label1.Text = label1Text;
    });
}

अब हमेशा इस पैटर्न का उपयोग करना न भूलें। या, SynchronizationContext.Post कोशिश करें। जो आपके लिए इसे बनाएगा:

private void button1_Click(object sender, EventArgs e)
{
    Task.Run(() =>
    {
        var label1Text = RunTooLong();
        SynchronizationContext.Current.Post((obj) =>
        {
            label1.Text = label1    Text);
        }, null);
    });
}


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow