ยังไงทำงานหนักหรอกยอมจำนนต่องานภายใต้ฮู้ดอยู่ใน Blazor WebAssembly?

0

คำถาม

ยังไง Task.Yield ทำงานภายใต้ฮู้ดอยู่ใน เสียงโมโน(mono)/WASM runtime (ซึ่งเป็นที่ถูกใช้โดย Blazor WebAssembly)?

เพื่อความชัดเจนฉันอยากจะเชื่อว่าฉันมีความเข้าใจขอ ยังไง Task.Yield ทำงาน อยู่อข่ายส่วนเฟรมเวิร์กแล้ว.อข่ายส่วนกลาง เสียงโมโน(mono)implementation ไม่ได้ดูต่างไปใน nutshell มันมาพร้อไปนี้:

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แต่ในที่สุดมันใช้บางอย่างของแพลตฟอร์มบนเว็บรูปแบบ api อยากรู้ตารางเวลา continuation เรียกกลับ? และถ้างั้นซึ่งหนึ่งสิ่ง(เหมือน queueMicrotask, setTimout, Promise.resove().thenเป็นต้)?


ปรับปรุงผมเพิ่งค้นพบว่า Thread.Sleep คือการจัดเตรียมไว้เช่นกันและมันจริง ช่วงตึกเหตุการณ์วงเธรด

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

คำตอบที่ดีที่สุด

5

มัน setTimeout. นั่นคือ considerable indirection ระหว่างนั้นแล้ว QueueUserWorkItemแต่นี่คือที่ที่มันกแก้วออกมา

ส่วนใหญ่ของ WebAssembly พาะ machinery สามารถถูกเห็นอยู่ใน การประชาสัมพันธ์ 38029. ที่ WebAssembly implementation ของ RequestWorkerThread เรียกส่วนตัววิธีการชื่อ QueueCallbackซึ่งก็คือติดตั้งเพื่อใช้งานใน C เป็นรหัส mono_wasm_queue_tp_cb. นี่อยู่ใน invokes mono_threads_schedule_background_jobซึ่งส่งโทรมา schedule_background_execซึ่งก็คือติดตั้งเพื่อใช้งานใน TypeScript เป็น:

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ซึ่ง delegates ต้อง RequestWorkerThread,การจัดเตรียมไว้ที่ด้านบน ThreadPoolWorkQueue.Dispatch ทำให้มีจำนวนของ asynchronous งานต้องเป็น dequeued และประหาร;ในหมู่พวกเขาพวกที่เรียกกลับผ่านไป QueueUserWorkItem ควรในที่สุดปรากฏกายแล้ว

2021-11-28 11:17:30

เป็นคำตอบแล้ว tks! แต่ geven มัน setTimeoutคุณช่วยอธิบายใหญ่วามแตกต่างชั้นมองเห็นตอนเวลาควงของ await new Promise(r => setTimeout(r, 0)) กับ JS interop กับเป็นเรื่องของ await Task.Yield? คือมันเป็นข้อบกพร่องในการทดสอบ? blazorrepl.telerik.com/QlFFQLPF08dkYRbm30
noseratio

queueMicrotask (ขอแย้งหน่อย setTimeout)ได้เป็นมาใกล้ชิดงผล: blazorrepl.telerik.com/QFbFGVFP10NWGSam57
noseratio

ฉันไม่สามารถเปิดได้ของ REPL ที่อยู่เชื่อมโยงดังนั้นฉันไม่สามารถบอกอะไรคุณหมายความว่ายังไง แต่ถ้าคุณศึกษาด้วยรหัสต้นทางของของ ThreadPoolWorkQueue.Dispatchคุณจะสังเกตมันมีบางซับซ้อนการจัดตารางเกี่ยวข้องกับเรื่องนี้เท่าที่ดีแล้วหนึ่ง setTimeout อาจจะรับใช้หลายรายการในคิวการพิมพ์.เน็ asynchronous งานซึ่งฉันคาดหวังที่จะเป็นเร็วกว่ากำลักัน setTimeout ส่งคนเดียวเรียกกลับมา
user3840170

แปลก repl เชื่อมโยงที่ไม่ทำงาน ถ้าคุณยังอยากลองมันเป็น gist: gist.github.com/noseratio/73f6cd2fb328387ace2a7761f0b0dadc. มันเป็น literrally 8000ms กับ 20ms. งั้นก็มาแทน setTimeout กับ queueMicrotaskและมันเกี่ยวกับเดียวกัน 20ms.
noseratio

ดูเหมือนมัน: setTimeout มันทำให้เบราว์เซอร์ระบวนการที่เหตุการณ์วในระหว่างคอลแบกแต่ง.เน็ runtime สามารถส่งคนหลาย asynchronous งานด้วยการโดดครั้งเดียว setTimeout เรียกกลับ(dequeuing พวกเขาเกือบจะทันทีหลังจากพวกเขากำรายการในคิวการพิมพ์),ดังนั้นหลีกเลี่ยงที่อยู่เหนือศีรษะของ yielding ไปที่เหตุการณ์ด้วยนะ (ยัง browsers นอาจจะแสดง throttling บ setTimeout เรียซึ่งนี้ batching avoids.) นี้ได้รับผลเวลาอย่างน้อยก้อน queueMicrotask. ถึงแม้ว่าค timings คุณอาจจะไม่ถูกต้องต้องขอบคุณเป็คเตอร์ mitigations.
user3840170

ในภาษาอื่นๆ

หน้านี้อยู่ในภาษาอื่นๆ

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

ดังอยู่ในนี้หมวดหมู่

ดังคำถามอยู่ในนี้หมวดหมู่