有关.Net微信三公棋牌开发异步处理

2023-10-20 07:10

本文主要是介绍有关.Net微信三公棋牌开发异步处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

.Net微信三公棋牌开发异步处理论坛:aqiulian.com ,更多有关.Net异步处理的咨询Q:212303635。在处理很多IO逻辑时或者想在做后台计算时,我们都会用到并发。并发简单的分两种类型,一种是计算密集型,一种是IO密集型, 下面先介绍一下。

1. 计算密集型:
    如果我们把线程里面处理的事情看做一个任务,计算密集型就是这个任务主要做的事情是处理计算和逻辑,换句话说就是主要吃CPU。计算密集型的一个典型场景是在客户端程序后台做一些耗时的计算来避免界面假死。计算密集型任务并发处理,除了能避免某些线程阻塞外(比如界面假死),还能充分利用CPU资源,现在的PC机和笔记本一般都是双核或者4核,服务器更可能有好几个CPU,这样并发执行可以让计算机同时执行多个任务。

2. IO密集型:IO密集型任务里面一般要处理大量IO操作,当然,只包含一个IO操作的任务我们也可以看成IO密集型,原因是IO操作一般都比较耗时。IO密集型的场景更多,比如我们需要读取多个文件或者请求多个WebService等。IO任务并发执行优点更多,主要是节省CPU资源和加快处理速度。因为很多IO操作都比较耗时,但它们又基本用不到CPU,所以如果我们用单线程来处理,CPU可能长时间处于阻塞状态,啥活也不干,这样很浪费CPU资源。同时单线程使得IO操作只能一个一个执行,时间上也会更长。

    下面用几个简单的例子介绍如何在.Net里用线程池和异步来实现并发(当日你也可以直接创建线程来做)。

1. 最土鳖的例子,单任务计算密集型

   将一个计算密集型任务加入线程池,线程池会在有线程闲的时候执行该任务:
   

复制代码
        private static void Sample2(){ThreadPool.QueueUserWorkItem(count => Run((int)count), 20);}private static void Run(int count){for (int i = 0; i < count; ++i){Console.WriteLine(i);Thread.Sleep(100);}Console.WriteLine("finished");}
复制代码

上面的Run可以有任意的参数组合的委托,但是能加入QueueUserWorkItem的方法只能带一个object参数,需要打包一个参数类,然后在lambda里面分解后传给Run,也可以直接用一个字典当参数类。如果需要在计算完成时做一些处理,可以用下面的异步方法。 

 

复制代码
private static void Sample1(){Action<int> a = c =>{Run(c);};//异步执行操作,注意在Callback里面调用EndInvoke,//否则可能会有资源泄漏a.BeginInvoke(20, ar =>{a.EndInvoke(ar);}, null);}
复制代码

  完成处理的代码可以跟在a.EndInvoke(ar);后面。注意:EndInvoke最好在会掉里面调用,不然可能会造成资源泄漏,或某些内存无法回收。

 

2. 还是很土鳖的例子,异步读取一个文件添加行号然后打印
   这样在文件读取的IO操作过程中,CPU可以空出来做其他事情。
   

复制代码
    public class AddLineNum{/// <summary>/// 异步方式读取文件并加行号显示/// /// 总共分三步:/// 1. 前期准备工作,开始读文件,使用当前线程执行/// 2. 文件异步读取,这个步骤将不占用线程和CPU资源/// 3. 读取数据处理和显示,在第三个线程里执行/// </summary>/// <param name="file"></param>public AddLineNum(string file){_file = file;}/// <summary>/// 1. 开始读取文件/// </summary>public void Begin(){long fileSize = new FileInfo(_file).Length;_buffer = new byte[fileSize];FileStream reader = File.OpenRead(_file);reader.BeginRead(_buffer, 0, (int)fileSize, ar =>{int count = reader.EndRead(ar);Console.WriteLine("Read length:{0}", count);End();//处理读取数据}, null);}/// <summary>///  2.  处理读到的数据/// </summary>private void End(){string text = Encoding.UTF8.GetString(_buffer);string[] lines = text.Split(new string[]{Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries);for (int i = 0; i < lines.Length; ++i){Console.WriteLine(String.Format("{0}:{1}", i, lines[i]));}}private string _file = "";private byte[] _buffer = null;}
复制代码

调用代码:

     AddLineNum apmOne = new AddLineNum("AddLineNum.cs");apmOne.Begin();

如注释里面所说,在处理文件读取时不占用CPU,异步带来的好处。

    

3. 稍微不土鳖的例子,同时开始多个web请求,在所有请求结束时汇总结果
   

复制代码
   public class CheckSiteStatus{public CheckSiteStatus(IList<string> sites){_sites = sites;}public void Begin(){_finishedCount = _sites.Count;foreach (string site in _sites){HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("http://" + site);req.Method = "HEAD";req.BeginGetResponse(ar =>{HttpWebRequest request = ar.AsyncState as HttpWebRequest;try{HttpWebResponse res = (HttpWebResponse)(request.EndGetResponse(ar));_statusDic[request.RequestUri.Host] = res.StatusCode;}catch (WebException exp){HttpWebResponse errRes = exp.Response as HttpWebResponse;if (errRes != null){_statusDic[request.RequestUri.Host] = errRes.StatusCode;}else{_statusDic[request.RequestUri.Host] = HttpStatusCode.NotFound;}}//完成一个Interlocked.Decrement(ref _finishedCount);if (_finishedCount <= 0)End();}, req);}}private void End(){int goodCount = 0;foreach (var pair in _statusDic){if (pair.Value == HttpStatusCode.OK){++goodCount;}Console.WriteLine("site:{0}, status:{1}", pair.Key, pair.Value);}Console.WriteLine("{0} of {1} can be connected.", goodCount, _statusDic.Keys.Count);}private Dictionary<string, HttpStatusCode> _statusDic = new Dictionary<string, HttpStatusCode>();private IList<string> _sites;private int _finishedCount = 0;}
复制代码

调用代码:

复制代码
        CheckSiteStatus checker = new CheckSiteStatus(new string[] {"www.baidu.com","www.google.com","www.soso.com","www.idiot.com/"});checker.Begin();
复制代码

例子中用_finishedCount跟踪执行完成个数,然后用Interlocked的方法实现同步控制。

 

4. 和上面例子3实现的功能相同,本土鳖常用的方法,主线程会阻塞浪费点CPU,但是代码更简洁清楚。

复制代码
    class CheckSiteStatus2{public static void Check(IList<string> sites){//:开始请求Dictionary<string, HttpWebRequest> reqs = new Dictionary<string, HttpWebRequest>();Dictionary<string, IAsyncResult> asyncs = new Dictionary<string,IAsyncResult>();foreach (string site in sites){HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("http://" + site);req.Method = "HEAD";reqs[site] = req;asyncs[site] = req.BeginGetResponse(null, null);}//:结束请求,更新状态Dictionary<string, HttpStatusCode> statusDic = new Dictionary<string, HttpStatusCode>();foreach (var pair in asyncs){HttpWebRequest request = reqs[pair.Key];try{HttpWebResponse res = (HttpWebResponse)(request.EndGetResponse(pair.Value));statusDic[request.RequestUri.Host] = res.StatusCode;}catch (WebException exp){HttpWebResponse errRes = exp.Response as HttpWebResponse;if (errRes != null){statusDic[request.RequestUri.Host] = errRes.StatusCode;}else{statusDic[request.RequestUri.Host] = HttpStatusCode.NotFound;}}}//:全部处理完时汇总处理int goodCount = 0;foreach (var pair in statusDic){if (pair.Value == HttpStatusCode.OK){++goodCount;}Console.WriteLine("site:{0}, status:{1}", pair.Key, pair.Value);}Console.WriteLine("{0} of {1} can be connected.", goodCount, statusDic.Keys.Count);}}
复制代码

调用代码:

复制代码
CheckSiteStatus2.Check(new string[] {"www.baidu.com","www.google.com","www.soso.com","www.idiot.com/"});
复制代码

上面直接在一个静态方法里面用一段代码实现,各个步骤也比较清楚。

这篇关于有关.Net微信三公棋牌开发异步处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/245529

相关文章

SpringBoot分段处理List集合多线程批量插入数据方式

《SpringBoot分段处理List集合多线程批量插入数据方式》文章介绍如何处理大数据量List批量插入数据库的优化方案:通过拆分List并分配独立线程处理,结合Spring线程池与异步方法提升效率... 目录项目场景解决方案1.实体类2.Mapper3.spring容器注入线程池bejsan对象4.创建

PHP轻松处理千万行数据的方法详解

《PHP轻松处理千万行数据的方法详解》说到处理大数据集,PHP通常不是第一个想到的语言,但如果你曾经需要处理数百万行数据而不让服务器崩溃或内存耗尽,你就会知道PHP用对了工具有多强大,下面小编就... 目录问题的本质php 中的数据流处理:为什么必不可少生成器:内存高效的迭代方式流量控制:避免系统过载一次性

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

Python实现批量CSV转Excel的高性能处理方案

《Python实现批量CSV转Excel的高性能处理方案》在日常办公中,我们经常需要将CSV格式的数据转换为Excel文件,本文将介绍一个基于Python的高性能解决方案,感兴趣的小伙伴可以跟随小编一... 目录一、场景需求二、技术方案三、核心代码四、批量处理方案五、性能优化六、使用示例完整代码七、小结一、

Python中 try / except / else / finally 异常处理方法详解

《Python中try/except/else/finally异常处理方法详解》:本文主要介绍Python中try/except/else/finally异常处理方法的相关资料,涵... 目录1. 基本结构2. 各部分的作用tryexceptelsefinally3. 执行流程总结4. 常见用法(1)多个e

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

PHP应用中处理限流和API节流的最佳实践

《PHP应用中处理限流和API节流的最佳实践》限流和API节流对于确保Web应用程序的可靠性、安全性和可扩展性至关重要,本文将详细介绍PHP应用中处理限流和API节流的最佳实践,下面就来和小编一起学习... 目录限流的重要性在 php 中实施限流的最佳实践使用集中式存储进行状态管理(如 Redis)采用滑动

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

MyBatis-plus处理存储json数据过程

《MyBatis-plus处理存储json数据过程》文章介绍MyBatis-Plus3.4.21处理对象与集合的差异:对象可用内置Handler配合autoResultMap,集合需自定义处理器继承F... 目录1、如果是对象2、如果需要转换的是List集合总结对象和集合分两种情况处理,目前我用的MP的版本