using System;
using System.Threading;
using System.Collections.Generic;
using System.Windows.Forms; namespace AsyncDemo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} class objstate //申明一个实体类
{
public string fname;
public string lname;
public DateTime birthday;
public objstate()
{
fname = "wang";
lname = "nima";
birthday = DateTime.Now;
}
public objstate(string fn, string ln)
{
fname = fn;
lname = ln;
//birthday = DateTime.Now;
}
} AsyncCallback callback;
objstate obj; #region easy demo
//申明委托
public delegate string deltest();
deltest begin;
private void button1_Click(object sender, EventArgs e)
{
begin = new deltest(method);
callback = new AsyncCallback(back);
obj = new objstate();//实例化类,该对象可以传入回调函数中
begin.BeginInvoke(back, obj);//异步执行method,界面不会假死,5秒后执行回调函数,弹出提示框
}
private void back(IAsyncResult ar)
{
string res = begin.EndInvoke(ar);
objstate obj = (objstate)(ar.AsyncState);//通过AsyncState获取传入的object
MessageBox.Show(res + "\n" + obj.fname + " " + obj.lname + " " + obj.birthday); } private string method()
{
Thread.Sleep(5000);
return "welcome to this world";
}
#endregion #region complex demo //申明委托
public delegate void deltest1();
deltest1 begin1;
public delegate string deltest2(List<string> list);
deltest2 begin2;
private void button2_Click(object sender, EventArgs e)
{
string id = Thread.CurrentThread.ManagedThreadId.ToString();
Thread.CurrentThread.Name = "MainThread";
richTextBox1.Text = "主线程线程ID:" + id + " 主线程名:" + Thread.CurrentThread.Name + "\n"; begin1 = new deltest1(method1);
callback = new AsyncCallback(back1); List<objstate> list = new List<objstate>();
for (int i = 0; i < 10; i++)
{
objstate obj = new objstate("James" + (i * i).ToString(), "Warke" + (i * 3).ToString());
list.Add(obj);
}
//delegate.BeginInvoke(parameter[] para, AsyncCallback callback, object obj)
//para是method方法的参数;
//callback是method方法执行完后在同一子线程中立即执行的回调函数;
//obj是一个可以传入回调函数中的object ,在回调函数中通过 IAsyncResult.AsyncState获取
begin1.BeginInvoke(back1, list); this.Location = new System.Drawing.Point(0, 0);
MessageBox.Show("主线程没有阻塞");
} private void back1(IAsyncResult ar)
{
begin1.EndInvoke(ar);
//回调函数中的线程ID与异步执行method时的线程ID相同,说明说明回调函数也是在子线程中执行
string id = Thread.CurrentThread.ManagedThreadId.ToString(); if (this.IsHandleCreated)
{
IAsyncResult iar = this.BeginInvoke(new Action(delegate()
{
richTextBox1.Text += "正在调用back函数 " + "当前线程ID:" + id + "\n";
}));
this.EndInvoke(iar);
}
List<objstate> list = (List<objstate>)(ar.AsyncState);//通过AsyncState获取传入的object
List<string> strList = new List<string>();
for (int i = 0; i < 10; i++)
{
Thread.Sleep(3000);
//winform中控件的属性设置或操作只能有主线程进行
//因此在子线程中需要调用 Control.BeginInvoke(Delegate method)方法 在主线程上对控件进行操作
//Control.BeginInvoke中传入的方法,应尽量只包含对控件操作的语句,这样主线程能够快速执行完对控件的操作,主界面不会假死
//Action<T>()是无返回值的泛型委托 Func<T>()是带返回值的泛型委托
//线程的执行有可能在窗口句柄创建完成前进行,此时会报错,因此 子线程中要异步操作主线程中的控件就需要在主线程的窗口句柄创建完成后进行
//句柄的类型是 IntPtr ,相当于windows中的身份证, 是一个指向指针的指针, 在内存中有固定的地址
//指针指向一块内存引用类或方法或程序集,不过内存中的地址会不断改变,系统需要通过一个指向指针的指针来记载数据地址的变更,便是句柄
if (this.IsHandleCreated)
{
IAsyncResult iar = this.BeginInvoke(new Action(delegate()
{
richTextBox1.Text += "正在调用back函数 " + "当前线程ID:" + id + " 正在给第" + (i + 1).ToString() + "个人赋值" + "\n";
}));
this.EndInvoke(iar);
}
DateTime now = DateTime.Now;
list[i].birthday = now;
string str = now.ToLongTimeString() + " " + list[i].fname + "." + list[i].lname;
strList.Add(str);
} begin2 = new deltest2(method2);
begin2.BeginInvoke(strList, back2, null);
}
private void back2(IAsyncResult ar)
{
//有返回值的方法,可以通过EndInvoke(IAsyncResult ar)方法获取返回值
string res = begin2.EndInvoke(ar);
//回调函数中的线程ID与异步执行method时的线程ID相同,说明说明回调函数也是在子线程中执行
string id = Thread.CurrentThread.ManagedThreadId.ToString(); if (this.IsHandleCreated)
{
IAsyncResult iar = this.BeginInvoke(new Action(delegate()
{
richTextBox1.Text += "正在调用back2函数 " + "当前线程ID:" + id + "\n";
}));
this.EndInvoke(iar); }
MessageBox.Show(res);
}
private void method1()
{
string id = Thread.CurrentThread.ManagedThreadId.ToString();
for (int i = 5; i > 0; i--)
{
Thread.Sleep(1000);
if (this.IsHandleCreated)
{
IAsyncResult iar = this.BeginInvoke(new Action(delegate()
{
richTextBox1.Text += "正在调用method方法 " + "当前线程ID:" + id + " " + i.ToString() + "秒后method方法,进入回调函数\n";
}));
this.EndInvoke(iar);
}
}
}
private string method2(List<string> list)
{
string id = Thread.CurrentThread.ManagedThreadId.ToString();
for (int i = 0; i < 10; i++)
{
Thread.Sleep(3000);
if (this.IsHandleCreated)
{
IAsyncResult iar = this.BeginInvoke(new Action(delegate()
{
richTextBox1.Text += "正在调用method2方法 " + "当前线程ID:" + id + "\n";
richTextBox1.Text += list[i] + "\n";
richTextBox1.Select(richTextBox1.TextLength, 0);
}));
this.EndInvoke(iar);
}
}
return "finish";
}
#endregion
}
}

  

AsyncCallback IAsyncResult的更多相关文章

  1. 异步编程(AsyncCallback委托,IAsyncResult接口,BeginInvoke方法,EndInvoke方法的使用小总结)

    http://www.cnblogs.com/panjun-Donet/archive/2009/03/03/1284700.html 让我们来看看同步异步的区别: 同步方法调用在程序继续执行之前需要 ...

  2. C# - 多线程 之 异步编程

    异步编程 同步编程,请求响应模型,同步化.顺序化.事务化. 异步编程,事件驱动模型,以 Fire and Forget 方式实现. 异步编程模式  -§- 异步编程模型 (APM) 模式: IAsyn ...

  3. .Net组件程序设计之异步调用

    .Net组件程序设计之异步调用 说到异步调用,在脑海中首先想到就是BeginInvoke(),在一些常用对象中我们也会常常见到Invoke()和BeginInvoke(), 要想让自己的组件可以被客户 ...

  4. C#异步方法的使用

    from:http://www.myext.cn/csharp/a_6765.html 也许业内很多高不成低不就的程序员都会对一些知识点会有些迷惑,原因是平常工作用的少,所以也就决定了你对这个事物的了 ...

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

    C#中的线程一(委托中的异步) 一.同步委托 我们平时所用的委托以同步居多,我们编写一个方法和相关委托进行演示: publicdelegatevoid DoSomethingDelegate(stri ...

  6. 介绍开源的.net通信框架NetworkComms框架 源码分析(十四)StreamTools

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 目前作者已经开源  许可是 ...

  7. (转) C#如何使用异步编程

    怎么使用异步,就是用委托进行处理,如果委托对象在调用列表中只有一个方法,它就可以异步执行这个方法.委托类有两个方法,叫做BeginInvoke和EndInvoke,它们是用来异步执行使用. 异步有三种 ...

  8. C#如何使用异步编程

    怎么使用异步,就是用委托进行处理,如果委托对象在调用列表中只有一个方法,它就可以异步执行这个方法.委托类有两个方法,叫做BeginInvoke和EndInvoke,它们是用来异步执行使用. 异步有三种 ...

  9. Socket Programming in C#--Getting Started

    Getting Started You can argue that one can overcome these shortcomings by multithreading meaning tha ...

随机推荐

  1. 小程序解析HTML5

    最近做项目的时候碰到一个问题,就是调用接口获取信息到页面上,内容与HTML5标签一起获取过来了.一起显示在微信端上.一般都是二次开发才有可能出现这种问题.通过查找方法,找到了一个可以把HTML5标签转 ...

  2. 模拟+细节题——cf1236D

    思路好想,细节多的令人发指.. /* 反着判断:走完每个点=走过的路程=n*m-k 然后暴力判每行每列的目的地 每次走都能使走的范围缩小一行或者一列 */ #include<bits/stdc+ ...

  3. mongodb副本集的内部机制(借鉴lanceyan.com)

    针对mongodb的内部机制提出以下几个引导性的问题: 副本集故障转移,主节点是如何选举的?能否手动干涉下架某一台主节点. 官方说副本集数量最好是奇数,为什么? mongodb副本集是如何同步的?如果 ...

  4. Golang 标准库log的实现

      原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://gotaly.blog.51cto.com/8861157/1406905 前 ...

  5. fatal error C1076: compiler limit : internal heap limit reached; use /Zm to specify a higher limit

    最近想用一下Xtreme ToolkitPro 界面库,安装后用VC6根据向导 产生一个工程,编译时出现如下的错误: fatal error C1076: compiler limit : inter ...

  6. linux 查看cpu,memory

    https://www.cnblogs.com/ctypyb2002/p/9792951.html

  7. Quartus II 使用 modelsim 仿真

    转自:http://www.cnblogs.com/emouse/archive/2012/07/08/2581223.html Quartus 中调用modelsim的流程 1. 设定仿真工具 as ...

  8. pcre2 正则库

    \S+ 不能匹配到字符串末尾的最后一个字段

  9. ajax 回传参数

    JSONObject json = new JSONObject(); json.put("msg", msg); json.put("success", co ...

  10. rpm升级时spec文件执行的流程

    转自:https://www.cnblogs.com/zafu/p/7423758.html %pre 和 %post 脚本片段分别在软件包安装前和安装后执行.%preun 和 %postun 脚本片 ...