异步委托

创建线程的一种简单方式是定义一个委托,并异步调用它

委托是方法的类型安全的引用

Delegate类还支持异步地调用方法。在后台,Delegate类会创建一个执行任务的线程
  • 投票,并检查委托是否完成了任务

    • 所创建的Delegate类提供了BeginInvoke()方法,该方法中,可以传递用委托类型定义的输入参数。

    • BeginInvoke()方法总是有AsyncCallback和Object类型的两个额外参数

    • BeginInvoke()方法返回类型:IAsyncResult

    • 代码示例

        static void Main(string[] args)
{
// synchronous method call
// TakesAWhile(1,3000); // asynchronous by using a delegate
TakesAWhileDelegate dl = TakesAWhile;
IAsyncResult ar = dl.BeginInvoke(1, 500, null, null);
while (!ar.IsCompleted)
{
// doing something else in the main thread
Console.Write(".");
Thread.Sleep(50);
}
int result = dl.EndInvoke(ar);
Console.WriteLine("result:{0}", result);
} public delegate int TakesAWhileDelegate(int data, int ms); static int TakesAWhile(int data, int ms)
{
Console.WriteLine("TakesAWhile started");
Thread.Sleep(ms);
Console.WriteLine("TakesAWhile completed");
return ++data;
}
  • 使用与IAsyncResult相关联的等待句柄

    • 使用AsyncWaitHandle属性可以访问等待句柄

    • 代码示例,在此将上述示例中的While循环更改一下即可,如下

            while (true)
{
Console.Write(".");
if (ar.AsyncWaitHandle.WaitOne(50, false))
{
Console.WriteLine("Can get the result now");
break;
}
}
  • 异步回调

    • 在BeginInvoke()方法的第3个参数中,可以传递一个满足AsyncCallback委托的需求的方法

    • 代码示例

            TakesAWhileDelegate dl = TakesAWhile;
dl.BeginInvoke(1, 500, TakesAWhileCompleted, dl);
for (int i = 0; i < 100; i++)
{
Console.Write(".");
Thread.Sleep(50);
}
        static void TakesAWhileCompleted(IAsyncResult ar)
{
if (ar == null)
throw new ArgumentNullException("ar");
TakesAWhileDelegate dl = ar.AsyncState as TakesAWhileDelegate;
Trace.Assert(dl != null, "Invalid object type"); int result = dl.EndInvoke(ar);
Console.WriteLine("result:{0}", result);
}

Thread类

  • Thread类可以创建和控制线程

  • 默认情况,Thread类创建线程是前台线程。线程池中的线程总是后台线程。

  • 只要有一个前台线程在运行,应用程序的进程就在运行。Thread类创建线程时,可以设置IsBackground属性,以确定该线程时前台线程还是后台线程

  • 代码示例

            var t1 = new Thread(ThreadMain) { Name = "MyNewThread", IsBackground = false };
t1.Start();
Console.WriteLine("Main thread ending now.");
        static void ThreadMain()
{
Console.WriteLine("Thread {0} started", Thread.CurrentThread.Name);
Thread.Sleep(3000);
Console.WriteLine("Thread {0} completed", Thread.CurrentThread.Name);
}

线程池

  • ThreadPool类托管,在需要时增减池中线程的线程数,直到最大的线程数

  • ThreadPool.QueueUserWorkItem()方法,传递一个WaitCallback类型的委托

  • 代码示例

            int nWorkerThreads;
int nCompletionPortThreads;
ThreadPool.GetMaxThreads(out nWorkerThreads, out nCompletionPortThreads);
Console.WriteLine("Max worker threads:{0},I/O completion threads:{1}",
nWorkerThreads, nCompletionPortThreads);
for (int i = 0; i < 5; i++)
{
ThreadPool.QueueUserWorkItem(JobForAThread);
}
        static void JobForAThread(object state)
{
for (int i = 0; i < 3; i++)
{
Console.WriteLine("loop{0},running inside pooled thread{1}",
i, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(50);
}
}

任务

  • .NET 4包含新名称空间 System.Threading.Tasks,它包含的类抽象出了线程功能。在后台使用ThreadPool.

  • 启动新任务

    • 实例化TaskFactory类,在其中把TaskMethod()方法传递给StartNew()方法
    • 使用Task类的构造函数,调用Task类的Start()方法
    • 示例代码
            //using task factory
TaskFactory tf = new TaskFactory();
Task t1 = tf.StartNew(TaskMethod); //using the task factory via a task
Task t2 = Task.Factory.StartNew(TaskMethod); //using Task constructor
Task t3 = new Task(TaskMethod);
t3.Start(); Task t4 = new Task(TaskMethod, TaskCreationOptions.PreferFairness);
t4.Start();
        static void TaskMethod()
{
Console.WriteLine("running in a task");
Console.WriteLine("Task id:{0}", Task.CurrentId);
}

C# 多线程初级汇总的更多相关文章

  1. Java 多线程初级汇总

    多线程概述 抢占式多任务 直接中断而不需要事先和被中断程序协商 协作多任务 被中断程序同意交出控制权之后才能执行中断 多线程和多进程区别? 本质的区别在于每个进程有它自己的变量的完备集,线程则共享相同 ...

  2. Windows 多线程知识点汇总

    一.什么叫原子性? 答:一个操作不会被分成两个时间片来执行,不会刚执行到一半,由于时间片到了,CPU就跑去执行其他线程了.在多线程环境中对一个变量进行读写时,我们需要有一种方法能够保证对一个值的操作是 ...

  3. java多线程知识点汇总(一)多线程基础

    1.什么叫多线程程序? 答:一个进程至少有一个线程在运行,当一个进程中出现多个线程时,就称这个应用程序是多线程应用程序. java编写的程序都是多线程的,因为最少有俩线程,main主线程和gc线程. ...

  4. java多线程知识点汇总(四)多线程知识点脉络图

    1.多线程安全问题 1)synchronized关键字:如何加锁的问题,选择synchronized方法还是synchnized代码块. 选择哪个锁问题,this对象,还是class对象(针对stat ...

  5. java多线程知识汇总(三)如何选择锁?如何加锁

    1.锁,保证的是被锁的代码,一次执行完毕才能被其他线程执行,锁保证了一个线程执行过程中不被其他线程打断.以保证数据的准确性. 2.数据的读写过程,是有冲突的,当一个线程正在读数据,另一个线程正在写同一 ...

  6. java多线程知识点汇总(二)多线程实例解析

    本实验主要考察多线程对单例模式的操作,和多线程对同一资源的读取,两个知识.实验涉及到三个类: 1)一个pojo类Student,包括set/get方法. 2)一个线程类,设置student的成员变量a ...

  7. CyclicBarrier 是如何做到等待多线程到达一起执行的?

    我们有些场景,是需要使用 多线各一起执行某些操作的,比如进行并发测试,比如进行多线程数据汇总. 自然,我们可以使用 CountDownLatch, CyclicBarrier, 以及多个 Thread ...

  8. #include <mutex>

    多线程初级 #include <iostream> #include <thread> #include <windows.h> #include <mute ...

  9. Java面试 32个核心必考点完全解析

    目录 课程预习 1.1 课程内容分为三个模块 1.2 换工作面临问题 1.3 课程特色 课时1:技术人职业发展路径 1.1 工程师发展路径 1.2 常见技术岗位划分 1.3 面试岗位选择 1.4 常见 ...

随机推荐

  1. JavaScript中的箭头函数

    1.定义 箭头函数相当于匿名函数,并且简化了函数定义.箭头函数有两种格式,一种像上面的,只包含一个表达式,连{ ... }和return都省略掉了.还有一种可以包含多条语句,这时候就不能省略{ ... ...

  2. Java使用PropertyDescriptor获取实体类中私有属性的值,并给私有属性赋值

    大家都知道Java类中的私有的(private)属性是获取不到的(即使使用继承依然获取不到),那如果非要获取私有属性的值怎么办呢?一般的做法是将该java类封装称为一个JavaBean,即封装该私有属 ...

  3. 【MEF】构建一个WPF版的ERP系统

    原文:[MEF]构建一个WPF版的ERP系统 引言 MEF是微软的一个扩展性框架,遵循某种约定将各个部件组合起来.而ERP系统的一大特点是模块化,它们两者的相性很好,用MEF构建一个ERP系统是相当合 ...

  4. 汇编 OR运算

    知识点:  OR运算  逻辑或  按位或 一.OR运算 12||1=1; 1||01=1; 0||0=0; || //逻辑或 | //按位或 int _tmain(int argc, _TCHA ...

  5. 与Web交互可用的图片Base64编码

    #ifndef ___BASE64_H___ #define ___BASE64_H___ #include <string> using namespace std; class CBa ...

  6. scala学习——(1)scala基础(上)

    scala> val x = 1 x: Int = 1 一.值与变量 值(val):赋值后不可变 val值名称:类型 = XXX 变量(var):赋值后可以改变  var变量名称:类型 = XX ...

  7. Python中类和对象在内存中是如何保存?

    类以及类中的方法在内存中只有一份,而根据类创建的每一个对象都在内存中需要存一份,大致如下图: 如上图所示,根据类创建对象时,对象中除了封装 name 和 age 的值之外,还会保存一个类对象指针,该值 ...

  8. 页面添加友盟(CNZZ)统计和事件追踪

    1. 在页面中引入友盟(CNZZ)统计的 JS 代码 <script type="text/javascript"> // 统计 var cnzz_protocol = ...

  9. MOSFET的小信号模型和频率响应

    这部分内容大部分参考W.Y.Choi的课堂讲义第三讲和第四讲:http://tera.yonsei.ac.kr/class/2007_1/main.htm 一.小信号模型 首先要明确一点,大部分情形M ...

  10. iOS开发面试题整理

    前言 本文借鉴整理了iOS高级开发常见的面试题,并且分博客一一分析,希望能和大家一起进步学习. 欢迎大家关注我的 Github