I/O线程

CLR线程池分为工作者线程(workerThreads)与I/O线程(completionPortThreads)两种:

  • 工作者线程是主要用作管理CLR内部对象的运作,通常用于计算密集的任务。
  • I/O(Input/Output)线程主要用于与外部系统交互信息,如输入输出,CPU仅需在任务开始的时候,将任务的参数传递给设备,然后启动硬件设备即可。等任务完成的时候,CPU收到一个通知,一般来说是一个硬件的中断信号,此时CPU继续后继的处理工作。在处理过程中,CPU是不必完全参与处理过程的,如果正在运行的线程不交出CPU的控制权,那么线程也只能处于等待状态,即使操作系统将当前的CPU调度给其他线程,此时线程所占用的空间还是被占用,而并没有CPU处理这个线程,可能出现线程资源浪费的问题。如果这是一个网络服务程序,每一个网络连接都使用一个线程管理,可能出现大量线程都在等待网络通信,随着网络连接的不断增加,处于等待状态的线程将会很消耗尽所有的内存资源。可以考虑使用线程池解决这个问题。

 对于I/O线程,我们可以将输入输出操作分成三个步骤:启动、实际输入输出、处理结果。用 于实际输入输出可由硬件完成,并不需要CPU的参与,而启动和处理结果也可以不在同一个 线程上,这样就可以充分利用线程资源。在.Net中通过以Begin开头的方法来完成启动,以 End开头的方法来处理结果,这两个方法可以运行在不同的线程,这样我们就实现了异步编 程了。

.NET为多个I/O操作都建立起了异步方法。例如:FileStream、TCP/IP、WebRequest、WebService等等。

APM模式异步编写模型是一种模式,该模式允许用更少的线程去做更多的操作,.NET Framework很多类也实现了该模式,同时我们也可以自定义类来实现该模式,(也就是在自定义的类中实现返回类型为IAsyncResult接口的BeginXXX方法和EndXXX方法)

EPM模式是事件的异步编程模式的简称, 支持基于事件的异步模式的类将有一个或多个后缀为Async的方法,同时还会有一个相应名为Completed后缀的事件,Async方法用于启动异步处理,而Completed事件将在异步处理完成之后通过事件来宣告异步处理的完成。注意,在使用EPM模式的时候,不管是完成了异步请求,还是在处理中出现异常,或者是终止异步处理,都必须要调用Compeleted处理程序

 APM异步调用I/O线程

static void Main(string[] args)
{
    //线程池中10个线程,10 I/O线程
    ThreadPool.SetMaxThreads(10, 10);

    //int maxThreads, portThreads;
    ThreadPool.GetAvailableThreads(out int maxThreads, out int portThreads);
    Console.WriteLine($"当前最大线程数:{maxThreads},最大I/O线程数:{portThreads}");

    //文件名 文件创建方式 文件权限 文件进程共享 缓冲区大小为1024 是否启动异步I/O线程为true
    FileStream stream = new FileStream(@"D:\123.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite, 1024, true);
    //这里要注意,如果写入的字符串很小,则.Net会使用辅助线程写,因为这样比较快
    byte[] bytes = Encoding.UTF8.GetBytes("hello");
    //异步写入开始,倒数第二个参数指定回调函数,最后一个参数将自身传到回调函数里,用于结束异步线程
    stream.BeginWrite(bytes, 0, (int)bytes.Length, new AsyncCallback(Callback), stream);
    Console.ReadKey();
}

static void Callback(IAsyncResult result)
{
    //显示线程池现状
    Thread.Sleep(2000);
    //通过result.AsyncState再强制转换为FileStream就能够获取FileStream对象,用于结束异步写入
    FileStream stream = (FileStream)result.AsyncState;
    stream.EndWrite(result);
    stream.Flush();
    stream.Close();
}

 

你可能感兴趣的:(C#)