कैसे करता है कार्य है । उपज काम में हुड के तहत Blazor WebAssembly?

0

सवाल

कैसे करता है Task.Yield काम में हुड के तहत मोनो/WASM रनटाइम (जो द्वारा इस्तेमाल किया जाता है Blazor WebAssembly)?

स्पष्ट करने के लिए, मुझे विश्वास है कि मैं एक अच्छी समझ है की कैसे Task.Yield काम करता है । NET Framework और .नेट कोर. मोनो कार्यान्वयन ज्यादा अलग नहीं लगती है, संक्षेप में, यह नीचे आता है यह करने के लिए:

static Task Yield() 
{
    var tcs = new TaskCompletionSource<bool>();
    System.Threading.ThreadPool.QueueUserWorkItem(_ => tcs.TrySetResult(true));
    return tcs.Task;
}

हैरानी की बात है, यह काम करता है में Blazor WebAssembly, भी (यह कोशिश करो ऑनलाइन):

<label>Tick Count: @tickCount</label><br>

@code 
{
    int tickCount = System.Environment.TickCount;

    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender) CountAsync();
    }

    static Task Yield() 
    {
        var tcs = new TaskCompletionSource<bool>();
        System.Threading.ThreadPool.QueueUserWorkItem(_ => tcs.TrySetResult(true));
        return tcs.Task;
    }

    async void CountAsync() 
    {
        for (var i = 0; i < 10000; i++) 
        {
            await Yield();
            tickCount = System.Environment.TickCount;
            StateHasChanged();
        }
    }
}

स्वाभाविक रूप से, यह सब होता है पर एक ही घटना पाश में धागा ब्राउज़र है, तो मुझे आश्चर्य है कि यह कैसे काम करता है पर निचले स्तर पर है.

मुझे संदेह है, यह हो सकता है के उपयोग की तरह कुछ Emscripten के Asyncify, लेकिन अंत में, यह करता है के कुछ प्रकार का उपयोग वेब मंच एपीआई अनुसूची करने के लिए एक निरंतरता कॉलबैक? और अगर ऐसा है, जो वास्तव में (जैसे queueMicrotask, setTimout, Promise.resove().then, आदि)?


अद्यतन, मैं अभी पता चला है कि Thread.Sleep कार्यान्वित किया जाता है के रूप में अच्छी तरह से और यह वास्तव में ब्लॉक घटना पाश धागा

.net async-await blazor c#
2021-11-24 06:13:47
1

सबसे अच्छा जवाब

5

यह setTimeout. वहाँ काफी है indirection के बीच है कि और QueueUserWorkItemहै , लेकिन यह है जहाँ यह नीचे से बाहर.

अधिकांश WebAssembly-विशिष्ट मशीनरी में देखा जा सकता है पीआर 38029. के WebAssembly के कार्यान्वयन RequestWorkerThread कॉल एक निजी विधि नाम QueueCallbackहै , जो लागू किया जाता है में सी कोड के रूप में mono_wasm_queue_tp_cb. इस में invokes mono_threads_schedule_background_jobहै , जो बदले में कॉल schedule_background_execहै , जो में लागू टाइपप्रति के रूप में:

export function schedule_background_exec(): void {
    ++pump_count;
    if (typeof globalThis.setTimeout === "function") {
        globalThis.setTimeout(pump_message, 0);
    }
}

के setTimeout कॉलबैक अंत तक पहुँचता है ThreadPool.Callbackहै , जो invokes ThreadPoolWorkQueue.Dispatch.

इसे के बाकी के लिए विशिष्ट नहीं है Blazor सब पर है, और अध्ययन किया जा सकता है द्वारा पढ़ने के स्रोत कोड ThreadPoolWorkQueue वर्ग. संक्षेप में, ThreadPool.QueueUserWorkItem enqueues कॉलबैक में एक ThreadPoolQueue. Enqueueing कॉल EnsureThreadRequestedहै , जो प्रतिनिधियों के लिए RequestWorkerThreadकार्यान्वित किया , के रूप में ऊपर. ThreadPoolWorkQueue.Dispatch कारणों में से कुछ की संख्या अतुल्यकालिक कार्य करने के लिए dequeued है और मार डाला; उनमें से, कॉलबैक पारित करने के लिए QueueUserWorkItem होना चाहिए अंत में दिखाई देते हैं ।

2021-11-28 11:17:30

एक महान जवाब है, tks! लेकिन geven यह setTimeoutसकता है , तुम समझा है कि आप एक बहुत बड़ी विसंगति मैं देख रहा हूँ जब समय के एक पाश await new Promise(r => setTimeout(r, 0)) जे एस के साथ interop बनाम एक पाश के await Task.Yield? वहाँ है में एक दोष का परीक्षण? blazorrepl.telerik.com/QlFFQLPF08dkYRbm30
noseratio

queueMicrotask (के रूप में करने का विरोध किया setTimeout) पैदा करता है एक बहुत करीब परिणाम: blazorrepl.telerik.com/QFbFGVFP10NWGSam57
noseratio

मैं खोल नहीं पा रहा हूँ की किसी भी REPL लिंक है, तो मैं नहीं बता सकते हैं क्या आप का मतलब है. लेकिन अगर आप अध्ययन के स्रोत कोड ThreadPoolWorkQueue.Dispatch, तुम नोटिस करेंगे कि वहाँ कुछ परिष्कृत निर्धारण शामिल के रूप में अच्छी तरह से, और एक setTimeout सेवा कर सकते हैं कई पंक्तिबद्ध .नेट अतुल्यकालिक कार्य है, जो मुझे उम्मीद किया जा करने के लिए की तुलना में तेजी से होने के प्रत्येक setTimeout प्रेषण एक एकल कॉलबैक.
user3840170

अजीब repl लिंक काम नहीं करते । यदि आप अभी भी यह कोशिश करने के लिए, यहाँ सार है: gist.github.com/noseratio/73f6cd2fb328387ace2a7761f0b0dadc. यह literrally 8000ms बनाम 20ms. तो बस की जगह setTimeout के साथ queueMicrotaskहै , और यह उसी के बारे में 20ms.
noseratio

लगता है जैसे कि यह: setTimeout बनाता है ब्राउज़र की घटना की प्रक्रिया में पाश के बीच कॉलबैक, लेकिन .NET रनटाइम प्रेषण कर सकते हैं कई अतुल्यकालिक कार्यों में एक एकल setTimeout कॉलबैक (dequeuing उन्हें लगभग तुरंत बाद वे पंक्तिबद्ध हैं), इस प्रकार से परहेज की भूमि के ऊपर से बेदखल करने की घटना पाश. (इसके अलावा, ब्राउज़र प्रदर्शन कर सकते हैं थ्रॉटलिंग पर setTimeout कॉल, जो इस batching से बचा जाता है.) यह एक प्रभाव पैदा करता मोटे तौर पर बराबर करने के लिए queueMicrotask. हालांकि समय आप कर रहे हैं शायद बहुत सही नहीं है, धन्यवाद करने के लिए भूत mitigations.
user3840170

अन्य भाषाओं में

यह पृष्ठ अन्य भाषाओं में है

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

इस श्रेणी में लोकप्रिय

लोकप्रिय सवाल इस श्रेणी में