اشتراکها
سورس باز شدن WCF
We’re excited to announce a new open source project on GitHub from the WCF team at Microsoft. This new version of WCF targets .NET Core and has been donated to the family of .NET Foundation open source projects.
.NET applications however rely on the ciphers provided by the OS, and the only way to get new ciphers into the OS is through a patch from Microsoft. Unsupported versions of Windows typically do not receive these patches, so over time you can expect an increasing number of websites to stop working with .NET applications.
اشتراکها
منابعی برای یادگیری NET. در سال 2020
اشتراکها
MSDN Magazine دیگر منتشر نخواهد شد
در برنامههای Blazor Server، تنها از یک نخ رابط کاربری واحد ( single UI thread ) استفاده نمیشود؛ بلکه هر نخی که در دسترس باشد، میتواند در موقع رندر، استفاده شود. علاوه بر این اگر از عملیات نامتقارن استفاده شود، زمانیکه به کلمهی کلیدی await میرسیم، آنگاه نخ اختصاص داده شدهی برای ادامه پردازش متد، ممکن است لزوما همان چیزی نباشد که آن را شروع کرده است. برای نشان دادن این موضوع مثالی را در پیش میگیریم.
کامپوننتی را با نام SynchronousInitComponent با کد زیر درنظر میگیریم. همانطور که از اسم آن مشخص است این کامپوننت به صورت متقارن یا همزمان پیادهسازی شده است:
در حقیقت در متد OnInitialized آن، مقدار نخ جاری را توسط Thread.ManagedThreadId به دست میآوریم. بنابراین شماره نخ جاری پس از رندر شدن کامپوننت، در صفحه نمایش داده میشود.
حال در کامپوننت دیگری برای مثال کامپوننت index، کامپوننت همزمان فوق را به شکل زیر فراخوانی میکنیم:
با این نتیجه:
همانطور که ملاحظه مینمایید شناسه نخ یکسانی برای هر فراخوانی کامپوننت نشان داده میشود. بدیهی است در صورتیکه شما همین کد را اجرا کنید، ممکن است شماره نخ برنامه شما با کد من یکی نباشد؛ اما نتیجه یکی است. یعنی در تمامی موارد، یک عدد مشاهده میشود.
حال همین آزمایش را با متدهای نامتقارن یا ناهمزمان انجام میدهیم. کامپوننت AsynchronousInitComponent را با کد زیر درنظر بگیرید:
این کامپوننت هم دقیقا شبیه کامپوننت قبلی است؛ با این تفاوت که IdOfRenderingThread، مجددا بعد از یک تاخیر یک ثانیهای مقداردهی شدهاست. این مقداردهی سبب رندر مجدد کامپوننت با تاخیر یک ثانیه میشود. حال در کامپوننت دیگری، کامپوننت غیرمتقارن فوق را به شکل زیر فراخوانی میکنیم:
با اجرا کردن برنامه، دقیقا نتایج، شبیه نتایج نتایج کامپوننت متقارن میباشد:
اما تنها بعد از یک ثانیه (await Task.Delay(1000)) ، متدهای OnInitializedAsync کامپوننتها، به پایان میرسند و مقدار IdOfRenderingThread را پیش از به پایان رسیدن رندر صفحه، به روز رسانی مینمایند. اینبار، دیگر مقادیر نخها متفاوت خواهند بود:
با توجه به مطالب مطرح شده به این نتیجه میرسیم که این موضوع میتواند هنگام استفاده از یک وابستگی غیر ایمن ( non-thread-safe dependency ) مانند DBContext در چندین کامپوننت باعث بروز مشکل شود. نمونهای از نحوهی رویارویی با مشکلات احتمالی آن، در اینجا و اینجا بررسی شدهاست.
کامپوننتی را با نام SynchronousInitComponent با کد زیر درنظر میگیریم. همانطور که از اسم آن مشخص است این کامپوننت به صورت متقارن یا همزمان پیادهسازی شده است:
<p>Sync rendered by thread @IdOfRenderingThread</p> @code { int IdOfRenderingThread; protected override void OnInitialized() { base.OnInitialized(); IdOfRenderingThread = System.Threading.Thread.CurrentThread.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
حال همین آزمایش را با متدهای نامتقارن یا ناهمزمان انجام میدهیم. کامپوننت AsynchronousInitComponent را با کد زیر درنظر بگیرید:
<p>Async rendered by thread @IdOfRenderingThread</p> @code { int IdOfRenderingThread; protected override async Task OnInitializedAsync() { // Runs synchronously as there is no code in base.OnInitialized(), // so the same thread is used await base.OnInitializedAsync().ConfigureAwait(false); IdOfRenderingThread = System.Threading.Thread.CurrentThread.ManagedThreadId; // Awaiting will schedule a job for later, and we will be assigned // whichever worker thread is next available await Task.Delay(1000).ConfigureAwait(false); IdOfRenderingThread = System.Threading.Thread.CurrentThread.ManagedThreadId; } }
@page "/async-init" <h1>Components with asynchronous OnInitializedAsync()</h1> @for (int i = 0; i < 5; i++) { <AsynchronousInitComponent/> }
Components with asynchronous OnInitializedAsync() Async rendered by thread 4 Async rendered by thread 4 Async rendered by thread 4 Async rendered by thread 4 Async rendered by thread 4
Components with asynchronous OnInitializedAsync() Async rendered by thread 7 Async rendered by thread 18 Async rendered by thread 10 Async rendered by thread 13 Async rendered by thread 11
اشتراکها