어떻게 작업입니다.수율에서 작업 후드에서 Blazor WebAssembly?

0

질문

어떻게 Task.Yield 에서 작업 후드에 모노/WASM 런타임 (에 의해 사용되는 Blazor WebAssembly)?

을 명확히 하고 내가 믿고 좋은 이해의 방법 Task.Yield 작동합 니다.NET 프레임워크 및.NET 핵심입니다. 모노 구현 하지 않는 모습이 훨씬 다른,간단히 말해서,그것은 이:

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();
        }
    }
}

자연적으로,그것은 모든 일에는 동일한 이벤트 루프레드는 브라우저에서,그래서 그것이 어떻게 작동하는지 궁금해 낮은 수준에 있습니다.

나고 의심할 수 있습을 활용하여 무언가가 다음과 같 데비안의 Asyncify지만,결국,그것을 사용하여 어떤 종류의 웹 플랫폼 API 을 예약하려면 지속 콜백? 그렇다면,하나는 정확하게(아 queueMicrotask, setTimout, Promise.resove().then,etc.)?


업데이트,나는 그냥 발견 Thread.Sleep 구현뿐만 아니라 실제로 블럭 이벤트 루프레드

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

최고의 응답

5

setTimeout. 가 상당한 간접 사과 QueueUserWorkItem하지만 이것은 그것이 바닥다.

대부분의 WebAssembly-특정 기계에서 볼 수 있는 홍보 38029. 이 WebAssembly 의 구현 RequestWorkerThread 전화인 방법이라는 이름 QueueCallback에서 구현되는 C 코드 mono_wasm_queue_tp_cb. 이에서 호출합 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를 호출하는 ThreadPoolWorkQueue.Dispatch.

그것의 나머지 부분은 특정하지 않습 Blazor 모두에서,그리고 공부하실 수 있습니다 읽어의 소스 코드 ThreadPoolWorkQueue 클래스입니다. 에서 짧은 ThreadPool.QueueUserWorkItem enqueues 콜백에 ThreadPoolQueue. 저장 통화 EnsureThreadRequested는 대리인 RequestWorkerThread구현합니다. ThreadPoolWorkQueue.Dispatch 는 몇 가지 원 비동기해야 하는 작업이 큐에서 제거되고 실행되 그 중에서도,전달된 콜백 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

나는 열 수 없습의 링크 복제,그래서 내가 말할 수 없어 당신이 무엇을 의미합니다. 하지만 공부하는 경우의 소스 코드 ThreadPoolWorkQueue.Dispatch에,당신은 것을 알 수 있는 정교한 예약이 참여뿐만 아니라,하나는 setTimeout 할 수 있는 여러 대기됩니다.NET 비동기 작업을 기대하는 것보다 빠를 수 있는 각 setTimeout 파견 하나의 콜백입니다.
user3840170

이상한 복제의 링크 작동하지 않습니다. 는 경우에도 당신은 여전히려 그것을 시도하고,여기의 요점: gist.github.com/noseratio/73f6cd2fb328387ace2a7761f0b0dadc. 그것은 literrally8000ms 대 20ms. 그럼 그냥 바꾸기 setTimeoutqueueMicrotask며,그것에 대해 동일한 20ms.
noseratio

그것처럼 보인다: setTimeout 만든 브라우저 프로세스 이벤트 루프 사이에 콜백하지만,.NET runtime 파견할 수 있습니다 여러 비동기업에 단일 setTimeout 콜백(제거 그 후 거의 즉시 그들은 대기),따라서 피하는 오버헤드를 산출하는 이벤트다. (또한,브라우저를 수행할 수 있는 제한에 setTimeout 전화,이 일괄 처리 방지.) 그러나 이렇게 하면 효과에 상당하는 queueMicrotask. 지만 타이밍 당신은 아마 매우 정확한 덕분에,Spectre 완화 기능.
user3840170

다른 언어로

이 페이지는 다른 언어로되어 있습니다

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