千家信息网

C#中ManualResetEvent如何实现线程的暂停与恢复

发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,这篇文章主要为大家分析了C#中ManualResetEvent如何实现线程的暂停与恢复的相关知识点,内容详细易懂,操作细节合理,具有一定参考价值。如果感兴趣的话,不妨跟着跟随小编一起来看看,下面跟着小
千家信息网最后更新 2025年02月01日C#中ManualResetEvent如何实现线程的暂停与恢复

这篇文章主要为大家分析了C#中ManualResetEvent如何实现线程的暂停与恢复的相关知识点,内容详细易懂,操作细节合理,具有一定参考价值。如果感兴趣的话,不妨跟着跟随小编一起来看看,下面跟着小编一起深入学习"C#中ManualResetEvent如何实现线程的暂停与恢复"的知识吧。

背景

前些天遇到一个需求,在没有第三方源码的情况下,刷新一个第三方UI,并且拦截到其ajax请求的返回结果。当结果为AVALIABLE的时候,停止刷新并语音提示,否则继续刷新。

分析这个需求,发现需要控制一个刷新循环的暂停与开始,因此网上搜到了通过ManualResetEvent实现线程的暂停与恢复。

ManualResetEvent介绍

ManualResetEvent是一个通过信号机制,实现线程间状态同步的类。常用的方法有以下三个:

  • WaitOne:阻止当前线程,直到收到信号

  • Reset:将事件状态设置为非终止状态,导致线程阻止

  • Set:将事件状态设置为终止状态,从而允许继续执行一个或多个等待线程

实现设计

1.通过CefSharp的谷歌浏览器插件请求第三方网站

2.具体交互逻辑如下

默认开启一个线程,并通过WaitOne挂起,等待手动开始自动刷新的指令
手动通过Set方法发送开始工作信号
执行完面操作后,通过Reset将线程再次挂起,并等待Ajax结果,判断Ajax结果,如果不等于AVALIABLE则再次恢复线程

        public Form1()        {            InitializeComponent();            var setting = new CefSettings();            setting.Locale = "zh-CN";            setting.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36";            // 避免页面加载不出来, 建议加上这句            Cef.Initialize(setting);            workerThread = new Thread(new ThreadStart(BeginListenWorkerAsync));            workerThread.IsBackground = true;            workerThread.Start();            this.停止自动监听ToolStripMenuItem.Enabled = false;        }        private async void BeginListenWorkerAsync()        {            while (true)            {                _eventBeginListenWorkList.WaitOne();  //1.默认挂起线程,等待信号                chromiumWebBrowser1.GetBrowser().MainFrame.ExecuteJavaScriptAsync(@"document.evaluate(""//*[@id='root']/div[1]/div[2]/div/div[2]/div[1]/div[1]/div/div[1]/button"", document).iterateNext().click()");                Thread.Sleep(1000);                chromiumWebBrowser1.GetBrowser().MainFrame.ExecuteJavaScriptAsync(@"document.evaluate(""//*[@id='root']/div[1]/div[2]/div/div[1]/div/div/div/div[2]/div[6]/div/button"", document).iterateNext().click()");                _eventBeginListenWorkList.Reset(); //3.页面执行完相应操作则再次挂起线程,等待ajax请求结果再判断是否恢复线程            }        }        private void 停止自动监听ToolStripMenuItem_Click(object sender, EventArgs e)        {            this.开始自动监听ToolStripMenuItem.Enabled = true;            this.停止自动监听ToolStripMenuItem.Enabled = false;            _eventBeginListenWorkList.Reset();            StartListen = false;        }        private void 开始自动监听ToolStripMenuItem_Click(object sender, EventArgs e)        {            this.开始自动监听ToolStripMenuItem.Enabled = false;            this.停止自动监听ToolStripMenuItem.Enabled = true;            _eventBeginListenWorkList.Set(); // 2.手动通过Set发送信号恢复线程,让其工作            StartListen = true;        }

3.现在我们需要定义RequestHandler来指定ResourceHandler拦截ajax请求

        private void Form1_Load(object sender, EventArgs e)        {            chromiumWebBrowser1.RequestHandler = new MyRequestHandler(this);            chromiumWebBrowser1.Load("https://www.xxxxxxxx.com/");        }

MyRequestHandler中需要指定自定义ResourceHandler

    public class MyRequestHandler : RequestHandler    {        Form1 _form;        public MyRequestHandler(Form1 form)        {            _form = form;        }        public static string AuthorizationValue;        protected override bool OnBeforeBrowse(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool userGesture,            bool isRedirect)        {            // 先调用基类的实现,断点调试            return base.OnBeforeBrowse(chromiumWebBrowser, browser, frame, request, userGesture, isRedirect);        }        protected override IResourceRequestHandler GetResourceRequestHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame,            IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling)        {            Console.WriteLine(request.Url);            if (request.Url.StartsWith("https://www.xxxxxxxxxxxxxxxx/api") && request.Headers.AllKeys.Contains("Authorization"))            {                AuthorizationValue = request.Headers["Authorization"];            }            return new MyResourceRequestHandler(_form);        }    }

4.最后ResourceRequestHandler拦截到ajax请求之后,如果结果不是AVALIABLE则通过StartListenFunc再次恢复线程

    public class MyResourceRequestHandler : ResourceRequestHandler    {        Form1 _form;        public MyResourceRequestHandler(Form1 form)        {            _form = form;        }        private Dictionary responseDictionary = new Dictionary();        protected override IResponseFilter GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response)        {            var dataFilter = new MemoryStreamResponseFilter();            responseDictionary.Add(request.Identifier, dataFilter);            return dataFilter;        }        protected override void OnResourceLoadComplete(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength)        {            MemoryStreamResponseFilter filter;            if (responseDictionary.TryGetValue(request.Identifier, out filter))            {                var data = filter.Data;                                if (request.Url.StartsWith("https://xxxxxxxxxxxxxxxxxxxx/oneapi"))                {                    var available = false;                    string s = System.Text.Encoding.UTF8.GetString(data, 0, data.Length);                    Console.WriteLine(s);                    if (!string.IsNullOrEmpty(s))                    {                        var responseData = JsonConvert.DeserializeObject(s);                        if (responseData != null && responseData.productPreviews != null)                        {                            foreach (var item in responseData.productPreviews)                            {                                if (item.schedule != null && item.schedule.status != null && item.schedule.status.name == "AVAILABLE")                                {                                    available = true;                                    Mp3Player.Play();                                    Action act = delegate () { _form.StopListen(); };                                    _form.Invoke(act);                                    break;                                }                            }                        }                    }                    if (!available && Form1.StartListen)                    {                        Form1.StartListenFunc();                    }                }                                filter.Dispose();            }        }    }

而StartListenFunc则是通过Set方法再次恢复了线程对ui的重复查询

        public static void StartListenFunc()        {            _eventBeginListenWorkList.Set();            StartListen = true;        }

C#是什么

C#是一个简单、通用、面向对象的编程语言,它由微软Microsoft开发,继承了C和C++强大功能,并且去掉了一些它们的复杂特性,C#综合了VB简单的可视化操作和C++的高运行效率,以其强大的操作能力、优雅的语法风格、创新的语言特性和便捷的面向组件编程从而成为.NET开发的首选语言,但它不适用于编写时间急迫或性能非常高的代码,因为C#缺乏性能极高的应用程序所需要的关键功能。

关于"C#中ManualResetEvent如何实现线程的暂停与恢复"就介绍到这了,更多相关内容可以搜索以前的文章,希望能够帮助大家答疑解惑,请多多支持网站!

线程 C# 监听 结果 信号 再次 状态 手动 方法 第三方 语言 强大 事件 内容 功能 性能 特性 知识 网站 跟着 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 网站数据库设计个人心得 江西智能软件开发报价 最新网络安全审查意见 网络安全政治安全的重要性 安徽etc服务器云空间 软件开发角色和部门怎么理解 小布助手一直都是连接服务器 金燕东互联网科技公司 免费iptv服务器软件 包头软件开发找哪家 闵行区企业金融网络技术服务 易语言外部数据库删除数据 保护数据库安全的一般方法 宁夏gps时钟同步服务器 数据字典是存储数据库的 chart怎么连接数据库 华夏名人数据库王兴 软件开发pc端和移动端 新疆学校网络安全责任书 嘉兴服务器机柜图片 网络安全建设新闻 电话宝服务器拒绝 云计算面向软件开发者 嘉兴学软件开发流程八个步骤 石油化工工业互联网科技有限公司 宁夏gps时钟同步服务器 外购软件开发费入什么科目 数据库与信息查询平台研究 敏捷软件开发原则模式和实践 传奇怪物数据库怎么导出
0