>>回傳《C# 并發編程》
- 1. 阻塞鎖
- 2. 異步鎖
- 3. 阻塞信號
- 4. 異步信號
- 5. 限流
同步的型別主要有兩種: 通信和資料保護,
1. 阻塞鎖
class LockClass
{
// 這個鎖會保護 _value,
private readonly object _mutex = new object();
private int _value;
public void Increment()
{
lock (_mutex)
{
_value = https://www.cnblogs.com/BigBrotherStone/p/_value + 1;
}
}
}
鎖的使用,有四條重要的規則,
- 限制鎖的作用范圍,
- 檔案中寫清鎖保護的內容,
- 鎖范圍內的代碼盡量少,
- 在控制鎖的時候絕不運行隨意的代碼
2. 異步鎖
class SemaphoreSlimClass
{
// 這個鎖保護 _value,
private readonly SemaphoreSlim _mutex = new SemaphoreSlim(1);
private int _value;
public async Task DelayAndIncrementAsync()
{
await _mutex.WaitAsync();
try
{
var oldValue = https://www.cnblogs.com/BigBrotherStone/p/_value;
await Task.Delay(TimeSpan.FromSeconds(oldValue));
_value = oldValue + 1;
}
finally
{
_mutex.Release();
}
}
}
規則在這里也同樣適用
- 限制鎖的作用范圍,
- 檔案中寫清鎖保護的內容,
- 鎖范圍內的代碼盡量少,
- 在控制鎖的時候絕不運行隨意的代碼
3. 阻塞信號
class ManualResetEventSlimClass
{
private readonly ManualResetEventSlim _initialized = new ManualResetEventSlim();
private int _value;
public int WaitForInitialization()
{
_initialized.Wait();
return _value;
}
public void InitializeFromAnotherThread()
{
_value = https://www.cnblogs.com/BigBrotherStone/p/13;
_initialized.Set();
}
}
如果 ManualResetEventSlim 不能滿足需求,還可考慮用 AutoResetEvent 、 CountdownEvent 或 Barrier
比喻:
ManualResetEventSlim的整個作業方法有點像人群通過大門AutoResetEvent事件像一個旋轉門,一次只允許一人通過,
4. 異步信號
class TaskCompletionSourceClass
{
private readonly TaskCompletionSource<object> _initialized = new TaskCompletionSource<object>();
private int _value1;
private int _value2;
public async Task<int> WaitForInitializationAsync()
{
await _initialized.Task;
return _value1 + _value2;
}
public void Initialize()
{
_value1 = 13;
_value2 = 17;
_initialized.TrySetResult(null);
}
}
信號是一種通用的通知機制
- 如果這個“信號”是一個用來在代碼段之間發送資料的訊息,那就考慮使用生產者/消費者佇列
- 不要讓通用的信號只是用來協調對共享資料的訪問,那種情況下,可使用鎖,
5. 限流
class MaxDegreeClass
{
//作業流限流
IPropagatorBlock<int, int> DataflowMultiplyBy2()
{
var options = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 10 };
return new TransformBlock<int, int>(data =https://www.cnblogs.com/BigBrotherStone/p/> data * 2, options);
}
// 使用 PLINQ
IEnumerable ParallelMultiplyBy2(IEnumerable values)
{
return values.AsParallel()
.WithDegreeOfParallelism(10)
.Select(item => item * 2);
}
// 使用 Parallel 類
void ParallelRotateMatrices(IEnumerable> matrices, float degrees)
{
var options = new ParallelOptions { MaxDegreeOfParallelism = 10 };
Parallel.ForEach(matrices, options, matrix => matrix.Invoke(degrees));
}
//并發性異步代碼可以用 SemaphoreSlim 來限流:
async Task DownloadUrlsAsync(
IEnumerable urls)
{
var httpClient = new HttpClient();
var semaphore = new SemaphoreSlim(10);
var tasks = urls.Select(async url =>
{
await semaphore.WaitAsync();
try
{
return await httpClient.GetStringAsync(url);
}
finally
{
semaphore.Release();
}
}).ToArray();
return await Task.WhenAll(tasks);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/75336.html
標籤:C#
上一篇:取消任務
下一篇:任務調度
