有关.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

相关文章

Go语言开发实现查询IP信息的MCP服务器

《Go语言开发实现查询IP信息的MCP服务器》随着MCP的快速普及和广泛应用,MCP服务器也层出不穷,本文将详细介绍如何在Go语言中使用go-mcp库来开发一个查询IP信息的MCP... 目录前言mcp-ip-geo 服务器目录结构说明查询 IP 信息功能实现工具实现工具管理查询单个 IP 信息工具的实现服

Python Transformers库(NLP处理库)案例代码讲解

《PythonTransformers库(NLP处理库)案例代码讲解》本文介绍transformers库的全面讲解,包含基础知识、高级用法、案例代码及学习路径,内容经过组织,适合不同阶段的学习者,对... 目录一、基础知识1. Transformers 库简介2. 安装与环境配置3. 快速上手示例二、核心模

一文详解Java异常处理你都了解哪些知识

《一文详解Java异常处理你都了解哪些知识》:本文主要介绍Java异常处理的相关资料,包括异常的分类、捕获和处理异常的语法、常见的异常类型以及自定义异常的实现,文中通过代码介绍的非常详细,需要的朋... 目录前言一、什么是异常二、异常的分类2.1 受检异常2.2 非受检异常三、异常处理的语法3.1 try-

Python使用getopt处理命令行参数示例解析(最佳实践)

《Python使用getopt处理命令行参数示例解析(最佳实践)》getopt模块是Python标准库中一个简单但强大的命令行参数处理工具,它特别适合那些需要快速实现基本命令行参数解析的场景,或者需要... 目录为什么需要处理命令行参数?getopt模块基础实际应用示例与其他参数处理方式的比较常见问http

Java Response返回值的最佳处理方案

《JavaResponse返回值的最佳处理方案》在开发Web应用程序时,我们经常需要通过HTTP请求从服务器获取响应数据,这些数据可以是JSON、XML、甚至是文件,本篇文章将详细解析Java中处理... 目录摘要概述核心问题:关键技术点:源码解析示例 1:使用HttpURLConnection获取Resp

Java中Switch Case多个条件处理方法举例

《Java中SwitchCase多个条件处理方法举例》Java中switch语句用于根据变量值执行不同代码块,适用于多个条件的处理,:本文主要介绍Java中SwitchCase多个条件处理的相... 目录前言基本语法处理多个条件示例1:合并相同代码的多个case示例2:通过字符串合并多个case进阶用法使用

Java实现优雅日期处理的方案详解

《Java实现优雅日期处理的方案详解》在我们的日常工作中,需要经常处理各种格式,各种类似的的日期或者时间,下面我们就来看看如何使用java处理这样的日期问题吧,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言一、日期的坑1.1 日期格式化陷阱1.2 时区转换二、优雅方案的进阶之路2.1 线程安全重构2

Redis消息队列实现异步秒杀功能

《Redis消息队列实现异步秒杀功能》在高并发场景下,为了提高秒杀业务的性能,可将部分工作交给Redis处理,并通过异步方式执行,Redis提供了多种数据结构来实现消息队列,总结三种,本文详细介绍Re... 目录1 Redis消息队列1.1 List 结构1.2 Pub/Sub 模式1.3 Stream 结

使用Python实现一个优雅的异步定时器

《使用Python实现一个优雅的异步定时器》在Python中实现定时器功能是一个常见需求,尤其是在需要周期性执行任务的场景下,本文给大家介绍了基于asyncio和threading模块,可扩展的异步定... 目录需求背景代码1. 单例事件循环的实现2. 事件循环的运行与关闭3. 定时器核心逻辑4. 启动与停

Python处理函数调用超时的四种方法

《Python处理函数调用超时的四种方法》在实际开发过程中,我们可能会遇到一些场景,需要对函数的执行时间进行限制,例如,当一个函数执行时间过长时,可能会导致程序卡顿、资源占用过高,因此,在某些情况下,... 目录前言func-timeout1. 安装 func-timeout2. 基本用法自定义进程subp