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

2023-12-31 11:38

本文主要是介绍有关.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/555916

相关文章

Django开发时如何避免频繁发送短信验证码(python图文代码)

《Django开发时如何避免频繁发送短信验证码(python图文代码)》Django开发时,为防止频繁发送验证码,后端需用Redis限制请求频率,结合管道技术提升效率,通过生产者消费者模式解耦业务逻辑... 目录避免频繁发送 验证码1. www.chinasem.cn避免频繁发送 验证码逻辑分析2. 避免频繁

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

Python进行JSON和Excel文件转换处理指南

《Python进行JSON和Excel文件转换处理指南》在数据交换与系统集成中,JSON与Excel是两种极为常见的数据格式,本文将介绍如何使用Python实现将JSON转换为格式化的Excel文件,... 目录将 jsON 导入为格式化 Excel将 Excel 导出为结构化 JSON处理嵌套 JSON:

PyQt5 GUI 开发的基础知识

《PyQt5GUI开发的基础知识》Qt是一个跨平台的C++图形用户界面开发框架,支持GUI和非GUI程序开发,本文介绍了使用PyQt5进行界面开发的基础知识,包括创建简单窗口、常用控件、窗口属性设... 目录简介第一个PyQt程序最常用的三个功能模块控件QPushButton(按钮)控件QLable(纯文本

Spring Boot 中的默认异常处理机制及执行流程

《SpringBoot中的默认异常处理机制及执行流程》SpringBoot内置BasicErrorController,自动处理异常并生成HTML/JSON响应,支持自定义错误路径、配置及扩展,如... 目录Spring Boot 异常处理机制详解默认错误页面功能自动异常转换机制错误属性配置选项默认错误处理

SpringBoot 异常处理/自定义格式校验的问题实例详解

《SpringBoot异常处理/自定义格式校验的问题实例详解》文章探讨SpringBoot中自定义注解校验问题,区分参数级与类级约束触发的异常类型,建议通过@RestControllerAdvice... 目录1. 问题简要描述2. 异常触发1) 参数级别约束2) 类级别约束3. 异常处理1) 字段级别约束

如何在Java Spring实现异步执行(详细篇)

《如何在JavaSpring实现异步执行(详细篇)》Spring框架通过@Async、Executor等实现异步执行,提升系统性能与响应速度,支持自定义线程池管理并发,本文给大家介绍如何在Sprin... 目录前言1. 使用 @Async 实现异步执行1.1 启用异步执行支持1.2 创建异步方法1.3 调用

基于Python开发一个图像水印批量添加工具

《基于Python开发一个图像水印批量添加工具》在当今数字化内容爆炸式增长的时代,图像版权保护已成为创作者和企业的核心需求,本方案将详细介绍一个基于PythonPIL库的工业级图像水印解决方案,有需要... 目录一、系统架构设计1.1 整体处理流程1.2 类结构设计(扩展版本)二、核心算法深入解析2.1 自

Java堆转储文件之1.6G大文件处理完整指南

《Java堆转储文件之1.6G大文件处理完整指南》堆转储文件是优化、分析内存消耗的重要工具,:本文主要介绍Java堆转储文件之1.6G大文件处理的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言文件为什么这么大?如何处理这个文件?分析文件内容(推荐)删除文件(如果不需要)查看错误来源如何避