91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C#怎么Task執行任務

發布時間:2022-06-09 13:49:41 來源:億速云 閱讀:232 作者:iii 欄目:開發技術

本篇內容介紹了“C#怎么Task執行任務”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

Task執行任務,等待任務完成

代碼:

//任務
Func<int> Funcs = () =>
{
    Console.WriteLine("任務開始");
    return 1 + 1;
};
 
//執行任務
Task<int> printRes = Task.Run(Funcs);
 
//等待任務完成
printRes.GetAwaiter().OnCompleted(() =>
{
    Console.WriteLine("異步執行結果:" + printRes.Result);        
});

運行:

任務開始
異步執行結果:2

C# Task任務隊列

需求

眾所周知,方法體內代碼是從上往下執行的,在我們工作中經常會遇到一些需要延時執行,但又必須按順序來執行的需求。這要怎么解決呢。微軟官方提供的Task API就是專門來解決這個問題的。那么下面就開始吧。

基本的Task用法

新建一個Winfrom項目

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace 線程2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            Task task1 = new Task(() =>
            {
                Thread.Sleep(400);
                Console.WriteLine("task1");
            });
            Task task2 = new Task(() =>
            {
                Thread.Sleep(300);
                Console.WriteLine("task2");
            });
            Task task3 = new Task(() =>
            {
                Thread.Sleep(200);
                Console.WriteLine("task3");
            });
            Task task4 = new Task(() =>
            {
                Thread.Sleep(100);
                Console.WriteLine("task4");
            });
            task1.Start();
            task2.Start();
            task3.Start();
            task4.Start();
        }
    }
}

運行:

C#怎么Task執行任務

由于各個任務內部延時不同,最先執行的Task1,反而最后一個執行完,如果既要做延時操作,又要求從任務按順序執行,要怎么解決呢?

讓Task任務按順序執行

修改代碼:

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace 線程2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private List<Task> TaskList = new List<Task>();
 
        private void Form1_Load(object sender, EventArgs e)
        {
            Task task1 = new Task(() =>
            {
                Thread.Sleep(400);
                Console.WriteLine("task1");
            });
            Task task2 = new Task(() =>
            {
                Thread.Sleep(300);
                Console.WriteLine("task2");
            });
            Task task3 = new Task(() =>
            {
                Thread.Sleep(200);
                Console.WriteLine("task3");
            });
            Task task4 = new Task(() =>
            {
                Thread.Sleep(100);
                Console.WriteLine("task4");
            });
 
            TaskList.Add(task1);
            TaskList.Add(task2);
            TaskList.Add(task3);
            TaskList.Add(task4);
 
            foreach (Task task in TaskList)
            {
                task.Start();
                task.Wait();
            }
        }
    }
}

運行:

C#怎么Task執行任務

用上面的方法雖然有效,你可以看看,點擊界面的時候,界面處鼠標指針會一直轉圈,導致winfrom界面卡住,無法操作,這是因為使用Thread.Sleep 導致主線程阻塞,下面就來解決UI界面卡死的問題。

使用異步委托解決UI界面卡死問題

代碼:

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace 線程2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
 
        private List<Task> TaskList = new List<Task>();
 
 
        private void Button_Calculate_Click(object sender, EventArgs e)
        {
            Task task1 = new Task(async () =>
            {
                await Task.Delay(TimeSpan.FromSeconds(4));
                Console.WriteLine("task1");
            });
            Task task2 = new Task(async () =>
            {
                await Task.Delay(TimeSpan.FromSeconds(3));
                Console.WriteLine("task2");
            });
            Task task3 = new Task(async () =>
            {
                await Task.Delay(TimeSpan.FromSeconds(2));
                Console.WriteLine("task3");
            });
            Task task4 = new Task(async () =>
            {
                await Task.Delay(TimeSpan.FromSeconds(1));
                Console.WriteLine("task4");
            });
 
            TaskList.Add(task1);
            TaskList.Add(task2);
            TaskList.Add(task3);
            TaskList.Add(task4);
 
            foreach (Task task in TaskList)
            {
                task.Start();
                task.Wait();
            }
        }
    }
}

運行:

C#怎么Task執行任務

用異步方式雖然界面不會卡住,但另一個問題來了,task.wait()方法似乎沒有效果。里面的任務隊列依然沒有按順序來執行。那么如何即使用異步執行,也不阻塞主線程,而且要任務按順序來執行呢?

異步任務隊列按順序執行

代碼:

private void Test()
{
    Task.Run(() =>
    {
        Task t1 = new Task(() => {
            Thread.Sleep(2000);
            Console.WriteLine("t1");
            num = 1;
        });
        t1.Start();
        t1.Wait();
        Task t2 = new Task(() => {
            Thread.Sleep(1000);
            Console.WriteLine("t2");
            num = 3;
        });
        t2.Start();
        t2.Wait();
        Console.WriteLine("線程執行完畢");
    });
}

運行:

C#怎么Task執行任務

效果是實現了,代碼看起來好搓啊,強迫癥都犯了,沒關系,可以使用更優雅的寫法:

private async void Test()
{
    await Task.Run(async () =>
    {
        await Task.Delay(4000);
        Trace.WriteLine("第1個線程執行");
    });
    await Task.Run(async () =>
    {
        await Task.Delay(3000);
        Trace.WriteLine("第2個線程執行");
    });
    await Task.Run(async () =>
    {
        await Task.Delay(2000);
        Trace.WriteLine("第3個線程執行");
    });
}

運行:

C#怎么Task執行任務

到此為止,功能就實現了,這個需求在Unity3d中使用協程很簡單的幾句就可以搞定,但在Winfrom等項目的開發中,確實有點繁瑣。

封裝任務隊列

下面的代碼我不認為是一個很好的寫法,需要添加任務后,還得手動去調用,如果能添加到任務隊列就不管了,讓其自己自動按順序來執行任務,豈不是更好,讀者如果有興趣自己去完善這個猜想。另外,在游戲開發中,比如RGP項目中,有專門的任務系統,它和我這個帖子的概念不能混為一談,RPG任務系統更多的偏向數據的存取,來獲取任務的完成狀態。

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
 
namespace Utils
{
    public class TaskQueue
    {
        /// <summary>
        /// 任務列表
        /// </summary>
        private List<Task> TaskList = null;
        /// <summary>
        /// 是否在執行任務中
        /// </summary>
        private bool isPerformTask = false;
        /// <summary>
        /// 執行完任務的回調
        /// </summary>
        public Action CallBack = null;
 
 
        private static TaskQueue _instance = null;
        public static TaskQueue Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new TaskQueue();
                return _instance;
            }
        }
 
        /// <summary>
        /// 添加任務
        /// </summary>
        /// <param name="task"></param>
        public void AddTask(Task task)
        {
            if (isPerformTask)
            {
                Console.WriteLine("[TaskQueue]任務正在執行中,此時不能做賦值操作");
                return;
            }
 
            if (task != null)
            {
                TaskList.Add(task);
            }
        }
 
        /// <summary>
        /// 執行任務
        /// </summary>
        public void PerformTask()
        {
            if (isPerformTask)
            {
                Console.WriteLine("[TaskQueue]任務正在執行中,不可重復調用");
                return;
            }
            if (TaskList == null || TaskList.Count == 0)
            {
                Console.WriteLine("[TaskQueue]任務列表為空");
                return;
            }         
 
            Task.Run(() =>
            {
                isPerformTask = true;
 
                foreach (Task item in TaskList)
                {
                    item.Start();
                    item.Wait();
                }
 
                TaskList.Clear();
                isPerformTask = false;
 
                if (CallBack != null) CallBack();
            });
        }
 
        private TaskQueue()
        {
            TaskList = new List<Task>();
        }
    }
}

調用:

Task task1 = new Task(() =>
{
    Thread.Sleep(1000);
    Console.WriteLine("t1");
});
Task task2 = new Task(() =>
{
    Thread.Sleep(2000);
    Console.WriteLine("t2");
});
Task task3 = new Task(() =>
{
    Console.WriteLine("t3");
});
Action callback = () =>
{
    Console.WriteLine("所有任務執行完成");
};
TaskQueue.Instance.AddTask(task1);
TaskQueue.Instance.AddTask(task2);
TaskQueue.Instance.AddTask(task3);
TaskQueue.Instance.CallBack = callback;
TaskQueue.Instance.PerformTask();

運行:

C#怎么Task執行任務

“C#怎么Task執行任務”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

红河县| 凤冈县| 元谋县| 会同县| 宝兴县| 伊宁县| 全州县| 团风县| 托里县| 吴川市| 固安县| 鲁甸县| 阿拉善右旗| 奇台县| 菏泽市| 雷山县| 扬中市| 新邵县| 思南县| 西乡县| 仙居县| 广元市| 三台县| 株洲县| 恩平市| 平潭县| 枣庄市| 新蔡县| 黄山市| 东乌珠穆沁旗| 宁国市| 静安区| 新建县| 逊克县| 镇赉县| 黎平县| 英德市| 阿城市| 萨嘎县| 进贤县| 苍溪县|