亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

線程安全發送異步/可等待 FIFO

線程安全發送異步/可等待 FIFO

C#
汪汪一只貓 2022-08-20 17:46:57
所以我正在為.System.Net.WebSockets.ClientWebSocket您如何看待我想出的以下方法,它是線程安全的嗎?重要的是,一次只執行 1 個線程,等待線程將按 FIFO 順序執行。_ws.SendAsync另一種解決方案是使用BlocklingCollection和生產者 - 消費者模式。但是 BlockingCollection 沒有異步等待功能,所以如果它是線程安全的,我更喜歡當前的解決方案。我也非常感謝其他建議。private ClientWebSocket _ws;private int _sendTicketCount = 0;private int _sendTicketCurrent = 1;public async Task SendAsync(string message){    if (_ws.State != WebSocketState.Open)        throw new Exception("Connection is not open");    try    {        int mySendTicket = Interlocked.Increment(ref _sendTicketCount);        if (mySendTicket != _sendTicketCurrent)        {            await Task.Run(() => SpinWait.SpinUntil(() => mySendTicket == _sendTicketCurrent)).ConfigureAwait(false);        }        var cancel = new CancellationTokenSource(5000);        var bytes = new ArraySegment<byte>(Encoding.UTF8.GetBytes(message));        await _ws.SendAsync(bytes, WebSocketMessageType.Text, true, cancel.Token).ConfigureAwait(false);    }    catch(Exception ex)    {        throw ex;    }    finally    {        Interlocked.Increment(ref _sendTicketCurrent);    }}
查看完整描述

2 回答

?
叮當貓咪

TA貢獻1776條經驗 獲得超12個贊

您有一個有多個生產者和一個消費者的情況。

您可以使用使用正確選項設置的操作塊來執行此操作。


查看完整回答
反對 回復 2022-08-20
?
炎炎設計

TA貢獻1808條經驗 獲得超4個贊

_sendTicketCurrent需要是易失性的,否則允許JIT將值緩存在寄存器中,這可能導致無限循環。除此之外,它看起來是線程安全的,除了這是對CPU的巨大浪費(SpinWait完全使用內核)。


另外,做真的沒有意義。無論如何,您都要持有一個線程,因此您可以在當前線程中執行等待。await Task.Run(() => SpinWait.SpinUntil(() => mySendTicket == _sendTicketCurrent))


為了以更優化的方式執行所需的操作,已經提供了一個開箱即用的異步兼容同步基元:SemaphoreSlim。


private SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);


public async Task SendAsync(string message)

{

    if (_ws.State != WebSocketState.Open)

        throw new Exception("Connection is not open");


    try

    {

        await _semaphore.WaitAsync().ConfigureAwait(false);


        var cancel = new CancellationTokenSource(5000);

        var bytes = new ArraySegment<byte>(Encoding.UTF8.GetBytes(message));

        await _ws.SendAsync(bytes, WebSocketMessageType.Text, true, cancel.Token).ConfigureAwait(false);

    }

    finally

    {

        _semaphore.Release();

    }

}


查看完整回答
反對 回復 2022-08-20
  • 2 回答
  • 0 關注
  • 150 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號