C#中的线程一(委托中的异步)

一、同步委托

我们平时所用的委托以同步居多,我们编写一个方法和相关委托进行演示:

publicdelegatevoid DoSomethingDelegate(string name);
//同步委托
public static void Start1()
{
Console.WriteLine("this is primary thread");
Console.WriteLine("main thread:{0},{1},{2}", Thread.CurrentThread.CurrentCulture, Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId);
//DoSomethingDelegate del = new DoSomethingDelegate(Method1);
//注意这里,简单起见还可以把一个方法名直接赋给一个委托类型
DoSomethingDelegate del = Method1;
del("this is delegate method");
}
//委托所关联的方法
public static void Method1(string name)
{
Console.WriteLine("sub thread: {0},{1},{2}", Thread.CurrentThread.CurrentCulture, Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId);
Console.WriteLine(name);
Thread.Sleep(TimeSpan.FromSeconds(3));
Console.WriteLine("sub thread other things...");
}

我们分析下这个Start1()方法,首先显示了主线程相关的信息,然后定义了一个委托类型del,利用del("this is delegate method")执行Method1(string name)方法,由于是同步委托,所以主线程在执行到Thread.Sleep(TimeSpan.FromSeconds(3));处会暂时挂起,3秒后才继续执行,然后才返回到Start1()方法中继续执行。

我们运行Start1()方法后看看执行顺序

可以看到,运行结果是按主线程的执行顺序依次往下执行。

二、异步委托

//异步委托
public static void Start2()
{
Console.WriteLine("main thread:{0},{1},{2}", Thread.CurrentThread.CurrentCulture, Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId);
//DoSomethingDelegate del = new DoSomethingDelegate(Method1);
DoSomethingDelegate del = Method1;
del.BeginInvoke("this is delegate method", null, null);
Console.WriteLine("main thread other things...");
}

此次我们利用委托的BeginInvoke方法进行方法调用,BeginInvoke的方法签名如下:

IAsyncResult  DoSomethingDelegate.BeginInvoke(string name,AsyncCallBack  callback,object @object)

那么利用BeginInvoke进行方法调用的结果如何呢?如结果显示,BeginInvoke调用的方法有一个子线程去调用,主线程没有被执行到,Thread.Sleep(TimeSpan.FromSeconds(3));这个方法,也就没有被挂起线程。

三、异步委托详解

刚才我们通过del.BeginInvoke("this is delegate method", null, null);这样就做到了异步调用,我们在编写代码中还有这样一种需求,如果你要进行异步调用,子线程执行的结果怎么返回给主线程呢?del.EndInvoke上场了!

//异步委托得到返回值,实际上为了得到返回值,阻碍了主线程
public static void Start3()
{
Console.WriteLine("main thread:{0},{1},{2}", Thread.CurrentThread.CurrentCulture, Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId);
//DoSomethingDelegate del = new DoSomethingDelegate(Method1);
DoSomethingDelegate2 del = Method2;
IAsyncResult result=del.BeginInvoke("this is delegate method",null,null);
string s = del.EndInvoke(result);
Console.WriteLine("得到返回值:" + s);
Console.WriteLine("main thread other things...");
}//异步委托所调用的方法,注意此方法有返回值
public static string Method2(string name)
{
Console.WriteLine("sub thread:{0},{1},{2}", Thread.CurrentThread.CurrentCulture, Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId);
Console.WriteLine(name);
Thread.Sleep(TimeSpan.FromSeconds(3));
Console.WriteLine("sub thread other things...");
return "返回委托值";
}

从实例代码中我们可以看到,我们为了得到异步方法的返回值写了这么两行代码:

IAsyncResult result=del.BeginInvoke("this is delegate method",null,null);
string s = del.EndInvoke(result);

我们查看执行结果:由运行结果可以看到,屏幕输出了返回值,但是Method2(string name)方法并没有被异步执行到!原因在于string s = del.EndInvoke(result);这句阻碍了主线程的继续执行,等子线程返回值后赋给s后,主线程才继续执行。这样写的后果就是:为了得到返回值,阻碍了主线程

我们刚才执行异步委托都是通过下面的代码来完成的

IAsyncResult result=del.BeginInvoke("this is delegate method",null,null);

我们将BeginInvoke方法的第二个和第三个参数都设置为了null,我们现在来看看这两个参数的作用!第二个参数AsyncCallBack  callback,这个参数实际上是一个回调委托,我们看此委托的定义:

public delegate void AsyncCallback(IAsyncResult ar);

什么是回调方法?就是说委托所调用的方法执行完毕后自动执行的方法,即上面的Method2(string name)方法被异步执行结束后所调用的方法。于是我们在定义一个跟AsyncCallback委托匹配的方法:

public static void CallBack(IAsyncResult result)
{
DoSomethingDelegate2 del = result.AsyncState as DoSomethingDelegate2;
string s = del.EndInvoke(result);
Console.WriteLine("得到返回值:" + s);
}
public static void Start4()
{
Console.WriteLine("main thread:{0},{1},{2}", Thread.CurrentThread.CurrentCulture, Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId);
DoSomethingDelegate2 del = Method2;
AsyncCallback callBack = CallBack;
del.BeginInvoke("this is delegate method", callBack, del);
Console.WriteLine("main thread other things...");
}
public static string  Method2(string name)
{
Console.WriteLine("sub thread:{0},{1},{2}", Thread.CurrentThread.CurrentCulture, Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId);
Console.WriteLine(name);
Thread.Sleep(TimeSpan.FromSeconds(3));
Console.WriteLine("sub thread other things...");
return "返回委托值";
}

从上面的代码可以看出,在CallBack方法中我们得到了Method2(string name)方法的返回值。并且整个过程是异步执行的!请看运行结果:

为了得到异步方法的返回值还可以这么做:

public static void Start4()
{
Console.WriteLine("main thread:{0},{1},{2}", Thread.CurrentThread.CurrentCulture, Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId);
DoSomethingDelegate2 del = Method2;
//另一种实现方法
del.BeginInvoke("this is delegate method", CallBack2, null);
Console.WriteLine("main thread other things...");
}
public static void CallBack2(IAsyncResult result)
{
AsyncResult ar = result as AsyncResult;
DoSomethingDelegate2 del = ar.AsyncDelegate as DoSomethingDelegate2;
string s=del.EndInvoke(ar);
Console.WriteLine("得到返回值:" + s);
}

这段代码的运行效果跟上面是一样的,只不过写法不同而已!

C#中的线程一(委托中的异步)的更多相关文章

  1. Java中的线程--并发库中的集合

    线程中的知识点基本都已经学完了,看看Java5并发库中提供的集合... 一.可堵塞队列 队列包含固定长度的队列和不固定长度的队列 ArrayBlockQueue中只有put()方法和take()方法才 ...

  2. mina2中的线程池

    一.Mina中的线程池模型 前面介绍了Mina总体的层次结构,那么在Mina里面是怎么使用Java NIO和进行线程调度的呢?这是提高IO处理性能的关键所在.Mina的线程调度原理主要如下图所示: A ...

  3. 浅析Java中的线程池

    Java中的线程池 几乎所有需要异步或并发执行任务的程序都可以使用线程池,开发过程中合理使用线程池能够带来以下三个好处: 降低资源消耗 提高响应速度 提高线程的可管理性 1. 线程池的实现原理 当我们 ...

  4. C# 委托高级应用----线程——创建无阻塞的异步调用(二)

    了解IAsyncResult 现在我们已经了解,EndInvoke可以给我们提供传出参数与更新后的ref参数:也可以向我们导出异步函数中的异常信息.例如,我们使用BeginInvoke调用了异步函数S ...

  5. 谈.Net委托与线程——创建无阻塞的异步调用(二)

    了解IAsyncResult 现在我们已经了解,EndInvoke可以给我们提供传出参数与更新后的ref参数:也可以向我们导出异步函数中的异常信息.例如,我们使用BeginInvoke调用了异步函数S ...

  6. C#中的线程(二) 线程同步基础

    1.同步要领 下面的表格列展了.NET对协调或同步线程动作的可用的工具:                       简易阻止方法 构成 目的 Sleep 阻止给定的时间周期 Join 等待另一个线程 ...

  7. C#中的线程(一)入门

    文章系参考转载,英文原文网址请参考:http://www.albahari.com/threading/ 作者 Joseph Albahari,  翻译 Swanky Wu 中文翻译作者把原文放在了& ...

  8. C#中的线程四(System.Threading.Thread)

    C#中的线程四(System.Threading.Thread) 1.最简单的多线程调用 System.Threading.Thread类构造方法接受一个ThreadStart委托,改委托不带参数,无 ...

  9. C#中的线程三 (结合ProgressBar学习Control.BeginInvoke)

    C#中的线程三(结合ProgressBar学习Control.BeginInvoke) 本篇继上篇转载的关于Control.BeginInvoke的论述之后,再结合一个实例来说明Cotrol.Begi ...

随机推荐

  1. [python]自动化将markdown文件转成html文件

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  2. Ubuntu16.04下部署golang开发环境

    一.需要文件 golang http://www.golangtc.com/download liteide http://www.golangtc.com/download/liteide 二.安装 ...

  3. crack.vbs病毒,优盘里所有文件全变成快捷方式

    去了一趟学校打印店,用优盘copy打印了点东西,当时在打印店电脑里打开优盘的时候里面就变成了快捷方式,但没怎么在意.回来之后在自己电脑上居然也这样了.网上一搜是中了crack.vbs病毒了.格式化优盘 ...

  4. webDriver环境搭建与测试

    1.安装jdk 2.安装eclipse 3.安装selenium 由于使用的是开发语言是java,因此需要安装java版的selenium包.下载地址:http://pan.baidu.com/s/1 ...

  5. java执行效率低,但效率就低吗?

    很多没用过java或者没怎么用过java的程序员都会说java执行效率低,这种言论时不时的在影响着我这个初级的java开发者. java执行效率低因如下几点导致(和C++比较): 1,java不允许内 ...

  6. .net sharepoint文档库操作

      /// <summary> /// 检查文档库 /// </summary> /// <param name="siteUrl"></ ...

  7. JavaScript-事件周期-点击替换颜色

    事件周期 DOM:3个阶段 1.捕获:从最外层元素,向内层元素,逐个记录绑定的事件处理函数.默认,暂不触发任何事件 2.目标触发:优先触发目标元素绑定的事件处理函数 目标元素:实际点击的元素 3.冒泡 ...

  8. 通过其他页面跳转到tableBar指示的界面

    通过代理实现 让tableBar遵从代理,让代理的实现方法设置 [self setSelectedIndex:2]; setSelectedIndex:2 代表tableBar的item第3个处于选中 ...

  9. #ing# CSS细节注意点

    目录: 常用简写 权重(优先级) Hack 常用简写 权重(优先级) Hack    etc

  10. Eclipse中支持js提示

    使用eclipse自带的插件,无需另外安装插件,具体步骤如下 1.打开eclipse→Windows→Preferences→Java→Editor→Content Assist 修改Auto Act ...