.net使用Task多執行緒執行任務 .net限制執行緒數量

邢帅杰發表於2024-05-21
k
using System.Text.Json;

namespace WinFormsApp
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 更新訊息框
        /// </summary>
        /// <param name="msg"></param>
        public void UpdateMsg(string msg)
        {
            if (txtMsg.InvokeRequired)
            {
                Action<string> action = UpdateMsg;
                Invoke(action, msg);
                return;
            }
            txtMsg.AppendText(msg + "\r\n");
            //滾動到底部
            txtMsg.ScrollToCaret();
        }

        /// <summary>
        /// 啟用、禁用 按鈕。
        /// </summary>
        /// <param name="enabled"></param>
        private void SetBtnEnable(bool enabled)
        {
            if (btnStart.InvokeRequired)
            {
                Action<bool> action = SetBtnEnable;
                Invoke(action, enabled);
                return;
            }
            btnStart.Enabled = enabled;
        }

        /// <summary>
        /// 開始執行執行緒
        /// </summary>
        private async void btnStart_Click(object sender, EventArgs e)
        {
            //開啟一個子執行緒,不然等待時會卡主執行緒。
            await Task.Run(async () => { await TestIt(); });
        }

        public async Task TestIt()
        {
            //搞個集合
            List<int> list = new List<int>();
            for (int i = 0; i < 10; i++)
            {
                list.Add(i);
            }

            //任務集合
            List<Task> tasks = new List<Task>();

            //執行方法體
            Func<int, string> func = (id) =>
            {
                using (var context = new XCGDbContext())
                {
                    var stus = context.Students.Where(x => x.Id == id).FirstOrDefault();
                    if (stus == null)
                    {
                        return "id:" + id + " 無資料";
                    }
                    var str = JsonSerializer.Serialize(stus);
                    return str;
                }
            };

            int maxTaskCount = 3;
            foreach (int i in list)
            {
                int k = i;
                tasks.Add(Task.Run(() =>
                {
                    var res = func(k);
                    UpdateMsg(res);
                }));
                //判斷執行緒數量不能超過最大設定數。
                if (tasks.Count > maxTaskCount)
                {
                    //等待任何一個完成,會卡當前執行緒。
                    Task.WaitAny(tasks.ToArray());
                    //排除掉已完成的任務
                    tasks = tasks.Where(t => t.Status != TaskStatus.RanToCompletion).ToList();
                }
            }

            TaskFactory taskFac = new TaskFactory();
            //不卡主執行緒,所有Task完成,才執行下面的操作
            await taskFac.ContinueWhenAll(tasks.ToArray(), arr =>
            {
                //全部完成,執行其他操作...
                UpdateMsg("執行完畢");
            });
        }
    }
}

相關文章