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

C#中多線程使用CancellationTokenSource進行線程管理

 更新時間:2025年09月30日 08:22:02   作者:鈴兒~響叮當(dāng)  
本文主要介紹了C#中多線程使用CancellationTokenSource進行線程管理,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1. Xml 代碼

<Grid Margin="15" HorizontalAlignment="Left">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="100" />
        <ColumnDefinition Width="100" />
        <ColumnDefinition Width="10" />
        <ColumnDefinition Width="120" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="40" />
        <RowDefinition Height="40" />
        <RowDefinition Height="40" />
        <RowDefinition Height="40" />
        <RowDefinition Height="40" />
        <RowDefinition Height="1*" />
    </Grid.RowDefinitions>

    <!--  添加任務(wù)  -->
    <Label Content="Task Number" Style="{StaticResource LabelStyle}" />
    <TextBox
        x:Name="xTxtTaskNum"
        Grid.Column="1"
        Style="{StaticResource TextBoxStyle}" />
    <Button
        Grid.Column="3"
        Click="BtnClick_CreateTasks"
        Content="創(chuàng)建任務(wù)"
        Style="{StaticResource BtnStyle}" />

    <!--  開始任務(wù)  -->
    <Label
        Grid.Row="1"
        Content="Task Index"
        Style="{StaticResource LabelStyle}" />
    <TextBox
        x:Name="xTxtStartIdx"
        Grid.Row="1"
        Grid.Column="1"
        Style="{StaticResource TextBoxStyle}" />
    <Button
        Grid.Row="1"
        Grid.Column="3"
        Click="BtnClick_StartTask"
        Content="開始該任務(wù)"
        Style="{StaticResource BtnStyle}" />

    <!--  結(jié)束任務(wù)  -->
    <Label
        Grid.Row="2"
        Content="Task Index"
        Style="{StaticResource LabelStyle}" />
    <TextBox
        x:Name="xTxtStopIdx"
        Grid.Row="2"
        Grid.Column="1"
        Style="{StaticResource TextBoxStyle}" />
    <Button
        Grid.Row="2"
        Grid.Column="3"
        Click="BtnClick_StopTask"
        Content="停止該任務(wù)"
        Style="{StaticResource BtnStyle}" />

    <!--  暫停任務(wù)  -->
    <Label
        Grid.Row="3"
        Content="Task Index"
        Style="{StaticResource LabelStyle}" />
    <TextBox
        x:Name="xTxtPauseIdx"
        Grid.Row="3"
        Grid.Column="1"
        Style="{StaticResource TextBoxStyle}" />
    <Button
        Grid.Row="3"
        Grid.Column="3"
        Click="BtnClick_PauseTask"
        Content="暫停該任務(wù)"
        Style="{StaticResource BtnStyle}" />

    <!--  恢復(fù)任務(wù)  -->
    <Label
        Grid.Row="4"
        Content="Task Index"
        Style="{StaticResource LabelStyle}" />
    <TextBox
        x:Name="xTxtResumeIdx"
        Grid.Row="4"
        Grid.Column="1"
        Style="{StaticResource TextBoxStyle}" />
    <Button
        Grid.Row="4"
        Grid.Column="3"
        Click="BtnClick_ResumTask"
        Content="恢復(fù)該任務(wù)"
        Style="{StaticResource BtnStyle}" />
</Grid>

2. 代碼實現(xiàn)

public partial class TestCancellationTokenThreads : Window
{
    private ConcurrentDictionary<int, TaskInfo> _dictTaskInfo = new();
    private int _taskNum = 0;

    public TestCancellationTokenThreads()
    {
        InitializeComponent();
    }

    private void BtnClick_CreateTasks(object sender, RoutedEventArgs e)
    {
        _taskNum = Convert.ToInt32(xTxtTaskNum.Text);

        for (int i = 0; i < _taskNum; i++)
        {
            TaskInfo taskInfo = new()
            {
                Name = $"Task{i + 1}",
                Task = null,
                Cts = null,
                IsPause = false,
            };
            _dictTaskInfo.TryAdd(i, taskInfo);
        }
        Debug.WriteLine($"{_taskNum}個任務(wù)創(chuàng)建成功!");
    }

    private void BtnClick_StartTask(object sender, RoutedEventArgs e)
    {
        if (string.IsNullOrEmpty(xTxtStartIdx.Text)) return;

        int idx = Convert.ToInt32(xTxtStartIdx.Text);
        if (idx < 0 || idx >= _taskNum)
        {
            Debug.WriteLine($"任務(wù)序號超出任務(wù)總數(shù){_taskNum}");
            return;
        }
        TaskInfo taskInfo = _dictTaskInfo[idx];

        if ((taskInfo.Cts != null && !taskInfo.Cts.IsCancellationRequested) || (taskInfo.Task != null && !taskInfo.Task.IsCompleted))
        {
            Debug.WriteLine($"任務(wù): {taskInfo.Name}正在運行...");
            return;
        }
        taskInfo.Cts = new();
        taskInfo.IsPause = false;   //啟動任務(wù)后,自動開始
        Debug.WriteLine("任務(wù)開始運行...");

        CancellationToken token = taskInfo.Cts.Token;
        //創(chuàng)建任務(wù)
        taskInfo.Task = Task.Run(async () =>
        {
            int numIdx = 0;
            //執(zhí)行任務(wù)的,用 Token 的 IsCancellationRequested
            while (!token.IsCancellationRequested)
            {
                if (!taskInfo.IsPause)
                {
                    Debug.WriteLine(numIdx);
                    numIdx++;
                }
                try
                {
                    await Task.Delay(1000, token);
                }
                catch (OperationCanceledException)
                {
                    break;  //取消則立刻退出
                }
            }
        }, token);
    }

    private async void BtnClick_StopTask(object sender, RoutedEventArgs e)
    {
        if (string.IsNullOrEmpty(xTxtStopIdx.Text)) return;

        int idx = Convert.ToInt32(xTxtStopIdx.Text);
        if (idx < 0 || idx >= _taskNum)
        {
            Debug.WriteLine($"任務(wù)序號超出任務(wù)總數(shù){_taskNum}");
            return;
        }
        TaskInfo taskInfo = _dictTaskInfo[idx];
        if (taskInfo.Cts == null || taskInfo.Task == null) return;

        //觸發(fā)取消的操作,用 Cts 的 IsCancellationRequested
        if (!taskInfo.Cts.IsCancellationRequested)
        {
            taskInfo.Cts.Cancel();
        }
        try
        {
            await taskInfo.Task.WaitAsync(TimeSpan.FromMilliseconds(3000));
        }
        catch (TimeoutException)
        {
            Debug.WriteLine($"任務(wù):{taskInfo.Name} 停止超時!");
        }
        finally
        {
            taskInfo.Cts.Dispose();
            taskInfo.Cts = null;
            taskInfo.Task = null;
        }
        Debug.WriteLine($"任務(wù):{taskInfo.Name} 已停止");
    }

    private void BtnClick_PauseTask(object sender, RoutedEventArgs e)
    {
        if (string.IsNullOrEmpty(xTxtPauseIdx.Text)) return;

        int idx = Convert.ToInt32(xTxtPauseIdx.Text);
        if (idx < 0 || idx >= _taskNum)
        {
            Debug.WriteLine($"任務(wù)序號超出任務(wù)總數(shù){_taskNum}");
            return;
        }
        TaskInfo taskInfo = _dictTaskInfo[idx];
        taskInfo.IsPause = true;
    }

    private void BtnClick_ResumTask(object sender, RoutedEventArgs e)
    {
        if (string.IsNullOrEmpty(xTxtResumeIdx.Text)) return;

        int idx = Convert.ToInt32(xTxtResumeIdx.Text);
        if (idx < 0 || idx >= _taskNum)
        {
            Debug.WriteLine($"任務(wù)序號超出任務(wù)總數(shù){_taskNum}");
            return;
        }
        TaskInfo taskInfo = _dictTaskInfo[idx];
        taskInfo.IsPause = false;
    }

}

public class TaskInfo
{
    public string? Name { get; set; }
    public Task? Task { get; set; }
    public CancellationTokenSource? Cts { get; set; }
    public bool IsPause { get => _isPause; set => _isPause = value; }
    public object Locker { get; set; } = new();

    //以這樣的方式,保留 volatile 的功能性
    //volatile: 適用于一個線程讀,一個線程寫的情況,并且是簡單類型的簡單操作 (不能用于 struct等、IsPause = !IsPause 這種 "修改+寫入"),并且只能字段
    private volatile bool _isPause; 
}

3. 運行

到此這篇關(guān)于C#中多線程使用CancellationTokenSource進行線程管理的文章就介紹到這了,更多相關(guān)C# 線程管理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Unity使用攝像機實現(xiàn)望遠鏡效果

    Unity使用攝像機實現(xiàn)望遠鏡效果

    這篇文章主要為大家詳細介紹了Unity攝使用像機實現(xiàn)望遠鏡效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • WPF?Trigger改變屬性無效問題排查示例詳解

    WPF?Trigger改變屬性無效問題排查示例詳解

    這篇文章主要為大家介紹了WPF?Trigger改變屬性無效問題排查示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • C#中靜態(tài)的深入理解

    C#中靜態(tài)的深入理解

    這篇文章詳細的介紹了C#中的靜態(tài),有需要的朋友可以參考一下
    2013-09-09
  • c# rsa注冊實現(xiàn)加密文字

    c# rsa注冊實現(xiàn)加密文字

    這篇文章主要介紹了c# rsa注冊實現(xiàn)加密文字,需要的朋友可以參考下
    2014-04-04
  • C#使用EF連接PGSql數(shù)據(jù)庫的完整步驟

    C#使用EF連接PGSql數(shù)據(jù)庫的完整步驟

    這篇文章主要給大家介紹了關(guān)于C#使用EF連接PGSql數(shù)據(jù)庫的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01
  • C#管道式編程的介紹與實現(xiàn)

    C#管道式編程的介紹與實現(xiàn)

    這篇文章主要給大家介紹了關(guān)于C#管道式編程的介紹與實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用C#具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • C#使用ODBC與OLEDB連接數(shù)據(jù)庫的方法示例

    C#使用ODBC與OLEDB連接數(shù)據(jù)庫的方法示例

    這篇文章主要介紹了C#使用ODBC與OLEDB連接數(shù)據(jù)庫的方法,結(jié)合實例形式分析了C#基于ODBC與OLEDB實現(xiàn)數(shù)據(jù)庫連接操作簡單操作技巧,需要的朋友可以參考下
    2017-05-05
  • 基于C#實現(xiàn)屏幕桌面截圖

    基于C#實現(xiàn)屏幕桌面截圖

    這篇文章主要為大家詳細介紹了如何利用C#實現(xiàn)屏幕桌面截圖以及左上角區(qū)域截圖功能,文中的示例代碼講解詳細,對我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以了解一下
    2022-12-12
  • Unity實現(xiàn)蘋果手機Taptic震動

    Unity實現(xiàn)蘋果手機Taptic震動

    這篇文章主要介紹了Unity實現(xiàn)蘋果手機Taptic震動,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • C# WinForm實現(xiàn)跨平臺串口通訊的解決方案

    C# WinForm實現(xiàn)跨平臺串口通訊的解決方案

    這篇文章主要為大家詳細介紹了如何使用C# WinForm實現(xiàn)真正的跨平臺串口通訊解決方案,包括Windows平臺的原生支持,Linux/macOS平臺的適配方案,以及第三方庫的集成使用,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-06-06

最新評論

会理县| 公安县| 威信县| 峨边| 平度市| 龙陵县| 陈巴尔虎旗| 黄石市| 镇巴县| 武平县| 亚东县| 航空| 福州市| 古浪县| 五华县| 朔州市| 法库县| 吕梁市| 阳泉市| 巴林左旗| 平南县| 定州市| 南宫市| 锡林郭勒盟| 凤翔县| 永济市| 肇庆市| 兰考县| 阿尔山市| 固镇县| 中宁县| 京山县| 弥渡县| 巴彦县| 通山县| 南丹县| 保定市| 双城市| 凤台县| 太原市| 承德县|