در برنامههای Blazor Server، تنها از یک نخ رابط کاربری واحد ( single UI thread ) استفاده نمیشود؛ بلکه هر نخی که در دسترس باشد، میتواند در موقع رندر، استفاده شود. علاوه بر این اگر از عملیات نامتقارن استفاده شود، زمانیکه به کلمهی کلیدی await میرسیم، آنگاه نخ اختصاص داده شدهی برای ادامه پردازش متد، ممکن است لزوما همان چیزی نباشد که آن را شروع کرده است. برای نشان دادن این موضوع مثالی را در پیش میگیریم. کامپوننتی را با نام SynchronousInitComponent با کد زیر درنظر میگیریم. همانطور که از اسم آن مشخص است این کامپوننت به صورت متقارن یا همزمان پیادهسازی شده است: <p>Sync rendered by thread @IdOfRenderingThread</p> @code { int IdOfRenderingThread; protected override void OnInitialized() { base.OnInitialized(); IdOfRenderingThread = System.Threading.Thread.CurrentThread.ManagedThreadId; } } در حقیقت در متد OnInitialized آن، مقدار نخ جاری را توسط Thread.ManagedThreadId به دست میآوریم. بنابراین شماره نخ جاری پس از رندر شدن کامپوننت، در صفحه نمایش داده میشود. حال در کامپوننت دیگری برای مثال کامپوننت index، کامپوننت همزمان فوق را به شکل زیر فراخوانی میکنیم: @page "/" <h1>Components with synchronous OnInitialized()</h1> @for (int i = 0; i < 5; i++) { <SynchronousInitComponent /> } با این نتیجه: Components with synchronous OnInitialized() Sync rendered by thread 4 Sync rendered by thread 4 Sync rendered by thread 4 Sync rendered by thread 4 Sync rendered by thread 4 همانطور که ملاحظه مینمایید شناسه ن, ...ادامه مطلب
اینطور که در این مطلب عنوان شده، ماوسهای قدیمی در اثر مشکلات سخت افزاری، میتوانند بهازای هر کلیک کاربر، دو سیگنال کلیک، ظرف مدت کوتاهی (برای مثال 5 میلی ثانیه) تولید کنند. برنامههای مبتنی بر Blazor، توسط متدهای نامتقارن میتوانند هردوی این سیگنالها را دریافت کرده و بنابراین متد مربوطه در کسری از ثانیه دوبار اجرا خواهد شد. برای رهایی از این مشکل میتوان از کدی شبیه زیر بهره جست: <button disabled="@_busy" Value="do-stuff" /> code{ private bool _busy = false; public async Task Handler() { if(_busy) retu; _busy = true; try { // do your thing } finally { _busy = false; } } } منطق آن ساده است؛ تا زمانی که اجرای متد، پایان نپذیرفتهاست، دکمهی مربوطه غیرفعال میگردد، تا نتوان دوباره روی آن کلیک کرد. اگر نمیخواهید به ازای هر کامپوننت، این کدهای تکراری را ایجاد کنید، میتوانید کدهای فوق را در قالب یک کامپوننت مانند زیر ایجاد کنید (با نام دلخواه HandleValidSubmitForm.razor): <EditForm Model="Model" OnValidSubmit="HandleValidSubmit"> @ChildContent?.Invoke(context) <button disabled="@_busy">Submit</button> </EditForm> @code { private bool _busy; [Parameter] public object? Model { get; set; } [Parameter] public EventCallback<EditContext> OnValidSubmit { get; set; } [Parameter] public RenderFragment<EditContext>? ChildContent { get; set; } private async Task HandleValidSubmit(EditContext editContext) { if (_busy) retu; _busy, ...ادامه مطلب