Wow – this was probably our biggest update ever! Version 2.0 of IdentityServer4 is not only incorporating all the feedback we got over the last year, it also includes the necessary updates for ASP.NET Core 2 – and also has a couple of brand new features. See the release notes for a complete list as well as links to issues and PRs.
On 16th November 2016, Nat Friedman and James Montemagno introduced Visual Studio for Mac, the newest member of the Visual Studio family at Connect(); 2016 event. I thought let's give it a try so I installed the same and went through the project templates available in it. This blog is kind of a getting started guide to install Visual Studio For Mac.
Data Dictionary در C#.NET
اکثر متدهای این کلاس thread-safe طراحی شدهاند؛ اما با یک استثناء: متد GetOrAdd آن thread-safe نیست:
TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory);
بررسی نحوهی کار با متد GetOrAdd
این متد یک کلید را دریافت کرده و سپس بررسی میکند که آیا این کلید در مجموعهی جاری وجود دارد یا خیر؟ اگر کلید وجود داشته باشد، مقدار متناظر با آن بازگشت داده میشود و اگر خیر، delegate ایی که به عنوان پارامتر دوم آن معرفی شدهاست، اجرا خواهد شد، سپس مقدار بازگشت داده شدهی توسط آن به مجموعه اضافه شده و در آخر این مقدار به فراخوان بازگشت داده میشود.
var dictionary = new ConcurrentDictionary<string, string>(); var value = dictionary.GetOrAdd("key1", x => "item 1"); Console.WriteLine(value); value = dictionary.GetOrAdd("key1", x => "item 2"); Console.WriteLine(value);
item 1 item 1
دسترسی همزمان به متد GetOrAdd امن نیست
ConcurrentDictionary برای اغلب متدهای آن به صورت توکار مباحث قفلگذاری چند ریسمانی را اعمال میکند؛ اما نه برای متد GetOrAdd. زمانیکه valueFactory آن در حال اجرا است، دسترسی همزمان به آن thread-safe نیست و ممکن است بیش از یکبار فراخوانی شود.
یک مثال:
using System; using System.Collections.Concurrent; using System.Threading.Tasks; namespace Sample { class Program { static void Main(string[] args) { var dictionary = new ConcurrentDictionary<int, int>(); var options = new ParallelOptions { MaxDegreeOfParallelism = 100 }; var addStack = new ConcurrentStack<int>(); Parallel.For(1, 1000, options, i => { var key = i % 10; dictionary.GetOrAdd(key, k => { addStack.Push(k); return i; }); }); Console.WriteLine($"dictionary.Count: {dictionary.Count}"); Console.WriteLine($"addStack.Count: {addStack.Count}"); } } }
dictionary.Count: 10 addStack.Count: 13
علت اینجا است که در این بین، متد GetOrAdd توسط ترد A فراخوانی میشود، اما key را در دیکشنری جاری پیدا نمیکند. به همین جهت شروع به اجرای valueFactory آن خواهد کرد. در همین زمان ترد B نیز به دنبال همین key است. ترد قبلی هنوز به پایان کار خودش نرسیدهاست که مجددا valueFactory متعلق به همین key اجرا خواهد شد. به همین جهت است که در ConcurrentStack اجرا شدهی در valueFactory، بیش از 10 آیتم موجود هستند.
الگویی برای مدیریت دسترسی همزمان امن به متد GetOrAdd
یک روش برای دسترسی همزمان امن به متد GetOrAdd، توسط تیم ASP.NET Core به صورت ذیل ارائه شدهاست:
// 'GetOrAdd' call on the dictionary is not thread safe and we might end up creating the pipeline more // once. To prevent this Lazy<> is used. In the worst case multiple Lazy<> objects are created for multiple // threads but only one of the objects succeeds in creating a pipeline. private readonly ConcurrentDictionary<Type, Lazy<RequestDelegate>> _pipelinesCache = new ConcurrentDictionary<Type, Lazy<RequestDelegate>>();
یک مثال:
namespace Sample { class Program { static void Main(string[] args) { var dictionary = new ConcurrentDictionary<int, Lazy<int>>(); var options = new ParallelOptions { MaxDegreeOfParallelism = 100 }; var addStack = new ConcurrentStack<int>(); Parallel.For(1, 1000, options, i => { var key = i % 10; dictionary.GetOrAdd(key, k => new Lazy<int>(() => { addStack.Push(k); return i; })); }); // Access the dictionary values to create lazy values. foreach (var pair in dictionary) Console.WriteLine(pair.Value.Value); Console.WriteLine($"dictionary.Count: {dictionary.Count}"); Console.WriteLine($"addStack.Count: {addStack.Count}"); } } }
10 1 2 3 4 5 6 7 8 9 dictionary.Count: 10 addStack.Count: 10
در این مثال دو تغییر صورت گرفتهاند:
الف) مقادیر ConcurrentDictionary به صورت Lazy معرفی شدهاند.
ب) متد GetOrAdd نیز یک مقدار Lazy را بازگشت میدهد.
زمانیکه از اشیاء Lazy استفاده میشود، خروجیهای بازگشتی از GetOrAdd، توسط این اشیاء Lazy محصور خواهند شد. اما نکتهی مهم اینجا است که هنوز value factory آنها فراخوانی نشدهاست. این فراخوانی تنها زمانی صورت میگیرد که به خاصیت Value یک شیء Lazy دسترسی پیدا کنیم و این دسترسی نیز به صورت thread-safe طراحی شدهاست. یعنی حتی اگر چند ترد new Lazy یک key مشخص را بازگشت دهند، تنها یکبار value factory متد GetOrAdd با دسترسی به خاصیت Value این اشیاء Lazy فراخوانی میشود و مابقی تردها منتظر مانده و تنها مقدار ذخیره شدهی در دیکشنری را دریافت میکنند و سبب اجرای مجدد value factory سنگین و زمانبر آن، نخواهند شد.
بر این مبنا میتوان یک LazyConcurrentDictionary را نیز به صورت ذیل طراحی کرد:
public class LazyConcurrentDictionary<TKey, TValue> { private readonly ConcurrentDictionary<TKey, Lazy<TValue>> _concurrentDictionary; public LazyConcurrentDictionary() { _concurrentDictionary = new ConcurrentDictionary<TKey, Lazy<TValue>>(); } public TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory) { var lazyResult = _concurrentDictionary.GetOrAdd(key, k => new Lazy<TValue>(() => valueFactory(k), LazyThreadSafetyMode.ExecutionAndPublication)); return lazyResult.Value; } }
در مثال فوق، به صورت صریحی پارامتر LazyThreadSafetyMode نیز مقدار دهی شدهاست. هدف از آن اطمینان حاصل کردن از آغاز این شیء Lazy با دسترسی به خاصیت Value آن، تنها توسط یک ترد است.
نمونهی دیگر کار با خاصیت ویژهی Value شیء Lazy را در مطلب «پشتیبانی توکار از ایجاد کلاسهای Singleton از دات نت 4 به بعد» پیشتر در این سایت مطالعه کردهاید.
Looking for a programming language to use for IoT projects? Having difficulty deciding which to choose? Selecting a language for IoT projects is as difficult as selecting a hardware platform. Here are top 6 programming languages that are best for IoT projects.
C#.NET for non-engineers.
The first course of "A Sr. Developer Course" courses. which contains:
1- C# Fundamentals for non-engineers.
2- DataBase for non-engineers.
3- Asp.NET WebForm for Non-engineers.
4- Application Architecture for no-engineers.
5- ASP.NET MVC for non-engineers.
6- Angular for non-engineers.
This is a course for who knows noting about C# and development if you know nothing about Array, variable, loop, and conditions you are in the right place.
at the end of this course, we will create one small university registration console application together.
You will learn in this course:
C#.NET
.NET Framework
Methods
Recursive methods
C# Primitive Types/Complex Types
conditions
switch case
Arrays
if statement
switch
loops
Creating a method
ref, out
enums
OOP/Object-oriented programing
Generics
Error handling
problem-solving
working with files
level: beginners to upper intermediate
With the rise of multi-core processors and multi-threading, Asynchronous Programming has become an essential tool for building efficient and responsive C# applications. Fortunately, C# provides a rich library for making Asynchronous calls. However, this complex and advanced topic can be challenging for many developers.
Windows Subsystem for Linux 2 (WSL 2) is one of the most popular features for developers on Windows 10 and 11. It has recently been made available on Windows Server 2022. With this addition, you can now run Linux containers on WSL 2 on Windows Server 2022 for development and testing purposes.
Here’s a summary of what’s new in this preview release:
- Support for route handler filters in minimal APIs
- Improved unit testability for minimal route handlers
- Bind using
TryParse
in MVC and API controllers - New
Results.Stream()
overloads - Improved HTTP/2 performance when using many streams on a connection
- New
ServerReady
event for measuring startup time - Developer exception page dark mode