最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#實現(xiàn)單線程異步互斥鎖的示例代碼

 更新時間:2024年01月17日 14:20:39   作者:CodeOfCC  
異步互斥鎖的作用是用于確保存在異步操作的上下文同步互斥,這篇文章主要為大家詳細(xì)介紹了C#如何實現(xiàn)單線程異步互斥鎖,文中的示例代碼講解詳細(xì),需要的可以參考下

前言

C#對異步的支持越來越成熟,async、await簡化了代碼也提高了可讀性,但由于在一段上下文中有了異步操作,意味著這段操作可能會被同時重復(fù)調(diào)用,如果本身沒有被設(shè)計可以重復(fù)調(diào)用的情況下,就很可能會出問題。

一、異步互斥鎖的作用是什么

異步互斥鎖的作用是用于確保存在異步操作的上下文同步互斥??梢詤⒖糵lutter的插件mutex功能與本文基本一樣。

示例一、創(chuàng)建和銷毀

有創(chuàng)建和銷毀兩個方法,兩個方法中都有異步操作,兩個方法可以單獨調(diào)用,但不可以同時調(diào)用。

單線程中連續(xù)調(diào)用創(chuàng)建和銷毀(不在同一個上下文無法用await),如果沒有互斥限制有可能出現(xiàn)如下的操作:

創(chuàng)建開始->創(chuàng)建異步操作->消息隊列->銷毀開始->銷毀異步操作->消息隊列->銷毀完成->消息隊列->創(chuàng)建完成

加入異步互斥鎖之后

加鎖->創(chuàng)建開始->創(chuàng)建完成->解鎖

加鎖等待->銷毀開始->銷毀完成->解鎖

二、如何實現(xiàn)

由于操作都是在單線程我們直接用標(biāo)識+隊列就可以實現(xiàn)一個互斥鎖。

1、標(biāo)識

(1)標(biāo)識是否鎖住

bool _lock = false;

(2)加鎖

_lock=true;

(3)解鎖

_lock=false;

2、異步通知

通過TaskCompletionSource可以實現(xiàn)異步通知

(1)創(chuàng)建對象

var tcs = new TaskCompletionSource();

(2)返回Task

return tcs.Task;

(3)通知完成

tcs.SetResult();

3、等待隊列

用一個隊列來記錄等待加鎖的請求。

(1)創(chuàng)建隊列

Queue<TaskCompletionSource> _queue = new Queue<TaskCompletionSource>();

(2) 等待加鎖

_queue.Enqueue(tcs);

(3)加鎖成功

_queue.Dequeue().SetResult();

三、完整代碼

/// <summary>
/// 異步鎖,非線程鎖,只能用于單線程異步環(huán)境中。
/// </summary>
class AsyncMutex
{
    Queue<TaskCompletionSource> _queue = new Queue<TaskCompletionSource>();
    bool _lock = false;
    /// <summary>
    /// 獲取鎖
    /// </summary>
    /// <returns>返回Task,await后即進入了鎖</returns>
    public Task Acquire()
    {
        if (_lock)
        {
            var tcs = new TaskCompletionSource();
            _queue.Enqueue(tcs);
            return tcs.Task;
        }
        _lock = true;
        return Task.CompletedTask;
    }
    /// <summary>
    /// 嘗試獲取鎖
    /// 因為是單線程環(huán)境,重復(fù)調(diào)用需要切換上下文,否則是無法成功的。
    /// 比如可以await Task.Delay(30);
    /// </summary>
    /// <returns>是否成功</returns>
    public bool TryAcquire()
    {
        if (_lock) return false;
        return _lock = true;
    }
    /// <summary>
    /// 釋放鎖
    /// </summary>
    public void Release()
    {
        if (_queue.Count > 0)
        {
            _queue.Dequeue().SetResult();
        }
        else
        {
            _lock = false;
        }
    }
}

四、使用示例

1、基本用法

直接加鎖

AsyncMutex _mtx = new AsyncMutex();
async void test()
{
    await _mtx.Acquire();
    //custom code
    _mtx.Release();
}

2、嘗試加鎖

加鎖成功才執(zhí)行操作

AsyncMutex _mtx = new AsyncMutex();
void test()
{
    if (_mtx.TryAcquire())
    {
        //custom code
        _mtx.Release();
    }
}

超時等待

AsyncMutex _mtx = new AsyncMutex();
async void test()
{
    //超時等待300ms
    bool isLock = false;
    for (int i = 0; i < 10; i++)
    {
        if (isLock = _mtx.TryAcquire()) break;
        await Task.Delay(30);
    }
    if (isLock)
    {
        //custom code
        _mtx.Release();
    }
}

3、加鎖對比

(1)未加鎖

async void test(int num)
{
    Console.WriteLine("enter " + num);
    //模擬異步操作
    await Task.Delay(10);
    Console.WriteLine("exit " + num);
}
//.net 6.0
test(1);
test(2);
test(3);

可能出現(xiàn)的組合,效果預(yù)覽

(2)加鎖

AsyncMutex _mtx = new AsyncMutex();
async void test(int num)
{
    await _mtx.Acquire();
    Console.WriteLine("enter " + num);
    //模擬異步操作
    await Task.Delay(10);
    Console.WriteLine("exit " + num);
    _mtx.Release();
}
//.net 6.0
test(1);
test(2);
test(3);

效果預(yù)覽

總結(jié)

本文簡單的實現(xiàn)了單線程的異步互斥鎖,實現(xiàn)起來相對簡單,但作用還是比較大的。雖然說有些情況的異步是可以在前期設(shè)計上避免同時調(diào)用,比如登錄按鈕點擊后出現(xiàn)蒙板不允許再次點擊,但是對于已存在的代碼出現(xiàn)了同時調(diào)用問題,此時有互斥鎖則可以避免大范圍改動代碼,有效解決問題。

以上就是C#實現(xiàn)單線程異步互斥鎖的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于C#單線程異步互斥鎖的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C# OpenVINO實現(xiàn)圖片旋轉(zhuǎn)角度檢測

    C# OpenVINO實現(xiàn)圖片旋轉(zhuǎn)角度檢測

    這篇文章主要為大家詳細(xì)介紹了C#?OpenVINO如何實現(xiàn)圖片旋轉(zhuǎn)角度檢測,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-02-02
  • C#實現(xiàn)簡單的計算器小程序

    C#實現(xiàn)簡單的計算器小程序

    這篇文章主要為大家詳細(xì)介紹了C#實現(xiàn)簡單的計算器小程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • C#使用GDI+實現(xiàn)生成驗證碼

    C#使用GDI+實現(xiàn)生成驗證碼

    這篇文章介紹了C#使用GDI+實現(xiàn)生成驗證碼的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • C#結(jié)合Free?Spire.PDF實現(xiàn)刪除PDF中的數(shù)字簽名

    C#結(jié)合Free?Spire.PDF實現(xiàn)刪除PDF中的數(shù)字簽名

    這篇文章主要為大家詳細(xì)介紹了C#如何結(jié)合Free?Spire.PDF實現(xiàn)刪除PDF中的數(shù)字簽名,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以參考一下
    2026-03-03
  • C#檢測pc光驅(qū)里是否插入了光盤的方法

    C#檢測pc光驅(qū)里是否插入了光盤的方法

    這篇文章主要介紹了C#檢測pc光驅(qū)里是否插入了光盤的方法,涉及C#針對光驅(qū)等硬件檢測操作的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07
  • C#簡單的加密類實例

    C#簡單的加密類實例

    AesManaged - 高級加密標(biāo)準(zhǔn)(AES) 對稱算法的管理類
    2013-03-03
  • 在C#中創(chuàng)建和讀取XML文件的實現(xiàn)方法

    在C#中創(chuàng)建和讀取XML文件的實現(xiàn)方法

    項目中需要將前臺頁面中的信息保存下來并存儲為xml文件格式到數(shù)據(jù)庫中去。因此我先在這里通過一個小實例來學(xué)習(xí)xml的創(chuàng)建與讀取
    2013-09-09
  • C#使用SemaphoreSlim進行并發(fā)控制的最佳實踐

    C#使用SemaphoreSlim進行并發(fā)控制的最佳實踐

    本文介紹了在C#中控制異步并發(fā)的標(biāo)準(zhǔn)解決方案SemaphoreSlim,,首先分析了不加控制的并發(fā)可能導(dǎo)致的問題和錯誤解決方案,接著詳細(xì)介紹了SemaphoreSlim的工作原理及其在生產(chǎn)環(huán)境中的使用方法,需要的朋友可以參考下
    2026-04-04
  • C#操作注冊表的方法詳解

    C#操作注冊表的方法詳解

    這篇文章主要介紹了C#操作注冊表的方法,結(jié)合實例形式較為詳細(xì)的分析了C#針對注冊表的創(chuàng)建、打開、讀取、寫入、修改、刪除等技巧,需要的朋友可以參考下
    2015-12-12
  • C#預(yù)處理指令之#line,#pragma warning 詳細(xì)解析

    C#預(yù)處理指令之#line,#pragma warning 詳細(xì)解析

    #line 指令可能由生成過程中的自動中間步驟使用。例如,如果行從原始的源代碼文件中移除,但是您仍希望編譯器基于文件中的原始行號生成輸出,則可以移除行,然后用 #line 模擬原始行號
    2014-01-01

最新評論

郯城县| 南川市| 子长县| 印江| 朝阳县| 托里县| 迁安市| 上犹县| 卓资县| 区。| 建平县| 会宁县| 正镶白旗| 嵊州市| 中阳县| 郁南县| 从化市| 嘉义市| 象山县| 海原县| 岳阳市| 集贤县| 元氏县| 郯城县| 水城县| 哈密市| 北票市| 闽侯县| 宁阳县| 盐池县| 无极县| 秦皇岛市| 独山县| 遂昌县| 神农架林区| 双城市| 宣汉县| 六枝特区| 淳化县| 仪征市| 武冈市|