技术思绪摘录旅行笔记
线程在开发中作用很大,也经常用到,本文以WinFrom演示Redis队列的案例,来看一看线程的启动和停止,已经线程中操作winform的控件。

Redis的配置,不在这篇文章里面介绍。


首先画个winform界面

image.png

先看代码

using System;
using System.Threading;
using System.Windows.Forms;
using EastWestWalk.NetFrameWork.Redis;

namespace Producer
{
    public partial class FrmMain : Form
    {
        private static string queueid = "MqId001";//队列id
        private static bool IsStrat = false;//是否继续生产信息
        private Thread StartThread = null;//生产线程
        private static bool IsEnd = false;//是否继续消费信息
        private Thread EndThread = null;//消费线程

        public FrmMain()
        {
            InitializeComponent();
        }

        /// <summary>
        ///开始生产按钮事件
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        private void btn_start_Click(object sender, EventArgs e)
        {
            if (btn_start.Text == "开始生产")
            {
                IsStrat = true;
                StartThread = new Thread(EnqueueRun);
                StartThread.Start();
                btn_start.Text = "正在生产";
            }
            else
            {
                IsStrat = false;
                Thread.Sleep(50);//这里很重要 不然线程任务还没结束 会报错
                if (StartThread != null && StartThread.ThreadState == ThreadState.Running)
                {
                    StartThread.Abort();
                    StartThread = null;
                }
                btn_start.Text = "开始生产";
            }
        }

        /// <summary>
        ///开始消费按钮事件
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        private void btn_end_Click(object sender, EventArgs e)
        {
            if (btn_end.Text == "开始消费")
            {
                IsEnd = true;
                EndThread = new Thread(DequeueRun);
                EndThread.Start();
                btn_end.Text = "正在消费";
            }
            else
            {
                IsEnd = false;
                Thread.Sleep(50);
                if (EndThread != null && EndThread.ThreadState == ThreadState.Running)
                {
                    EndThread.Abort();
                    EndThread = null;
                }
                btn_end.Text = "开始消费";
            }
        }


        /// <summary>
        /// 批量生产
        /// </summary>
        private void EnqueueRun()
        {
            using (var client = new DoRedisString(RedisUtility.RedisConfig))
            {
                int i = 0;
                while (IsStrat)
                {
                    string str = i + DateTime.Now.Ticks.ToString();
                    client.Core.EnqueueItemOnList(queueid, str);
                    txt_log.BeginInvoke(new Action(() =>
                    {
                        txt_log.AppendText($"生产:{str}\n");
                        txt_log.SelectionStart = txt_log.TextLength;
                        txt_log.ScrollToCaret();
                    }));
                    i++;
                    Thread.Sleep(20);
                }
            }
        }

        /// <summary>
        ///批量消费
        /// </summary>
        private void DequeueRun()
        {
            using (var client = new DoRedisString(RedisUtility.RedisConfig))
            {
                while (IsEnd)
                {
                    if (client.Core.GetListCount(queueid) > 0)
                    {
                        string result = client.Core.DequeueItemFromList(queueid);
                        txt_log.BeginInvoke(new Action(() =>
                        {
                            txt_log.AppendText($"消费:{result}\n");
                            txt_log.SelectionStart = txt_log.TextLength;
                            txt_log.ScrollToCaret();
                        }));
                        RedisUtility.SetRedis(result, $"消费成功:{result}", DateTime.Now.AddSeconds(30));
                        Thread.Sleep(20);
                    }
                    else
                    {
                        //如果当前队列为空,挂起1s
                        Thread.Sleep(1000);
                        client.Core.EnqueueItemOnList(queueid, "0");
                    }
                }
            }
        }
    }
}

两个线程,可以互不干扰的进行快速生产和消费,而且不会卡主线程

跨线程操作控件

                        txt_log.BeginInvoke(new Action(() =>
                        {
                            txt_log.AppendText($"消费:{result}\n");
                            txt_log.SelectionStart = txt_log.TextLength;
                            txt_log.ScrollToCaret();
                        }));


CarsonIT 微信扫码关注公众号 策略、创意、技术

留下您的脚步

 

最近评论

查看更多>>

站点统计

总文章数:275 总分类数:18 总评论数:88 总浏览数:128.24万

精选推荐

阅读排行

友情打赏

请打开您的微信,扫一扫