AsyncCallback IAsyncResult
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的更多相关文章
- 异步编程(AsyncCallback委托,IAsyncResult接口,BeginInvoke方法,EndInvoke方法的使用小总结)
http://www.cnblogs.com/panjun-Donet/archive/2009/03/03/1284700.html 让我们来看看同步异步的区别: 同步方法调用在程序继续执行之前需要 ...
- C# - 多线程 之 异步编程
异步编程 同步编程,请求响应模型,同步化.顺序化.事务化. 异步编程,事件驱动模型,以 Fire and Forget 方式实现. 异步编程模式 -§- 异步编程模型 (APM) 模式: IAsyn ...
- .Net组件程序设计之异步调用
.Net组件程序设计之异步调用 说到异步调用,在脑海中首先想到就是BeginInvoke(),在一些常用对象中我们也会常常见到Invoke()和BeginInvoke(), 要想让自己的组件可以被客户 ...
- C#异步方法的使用
from:http://www.myext.cn/csharp/a_6765.html 也许业内很多高不成低不就的程序员都会对一些知识点会有些迷惑,原因是平常工作用的少,所以也就决定了你对这个事物的了 ...
- C#中的线程一(委托中的异步)
C#中的线程一(委托中的异步) 一.同步委托 我们平时所用的委托以同步居多,我们编写一个方法和相关委托进行演示: publicdelegatevoid DoSomethingDelegate(stri ...
- 介绍开源的.net通信框架NetworkComms框架 源码分析(十四)StreamTools
原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架 作者是英国人 以前是收费的 目前作者已经开源 许可是 ...
- (转) C#如何使用异步编程
怎么使用异步,就是用委托进行处理,如果委托对象在调用列表中只有一个方法,它就可以异步执行这个方法.委托类有两个方法,叫做BeginInvoke和EndInvoke,它们是用来异步执行使用. 异步有三种 ...
- C#如何使用异步编程
怎么使用异步,就是用委托进行处理,如果委托对象在调用列表中只有一个方法,它就可以异步执行这个方法.委托类有两个方法,叫做BeginInvoke和EndInvoke,它们是用来异步执行使用. 异步有三种 ...
- Socket Programming in C#--Getting Started
Getting Started You can argue that one can overcome these shortcomings by multithreading meaning tha ...
随机推荐
- IDHTTP
Delphi IDHTTP用法详解 一.IDHTTP的基本用法 IDHttp和WebBrowser一样,都可以实现抓取远端网页的功能,但是http方式更快.更节约资源,缺点是需要手动维护cook,连接 ...
- 经典sql题练习50题
-- 1.查询"01"课程比"02"课程成绩高的学生的信息及课程分数 select a.* ,b.s_score as 01_score,c.s_score a ...
- ZROI week1
\[ZROI day1\] \[Grid\] 题目描述 给定一个矩阵,小写字母,求一条路径使得从\((1,1) -> (n,m)\),字典序最小,并且每次只能向右或者向下. 题解 先考虑如果没有 ...
- mac 堡垒机传文件
安装zssh brew install zssh 上传文件 zssh登陆上跳板机 在跳板机上ssh到相应服务器 在服务器上cd至相应要放上传文件的目录 rz -bye //在远程服务器的相应目录上运行 ...
- JAVA学习之数组
一.数组定义同一种类型数据的集合,其实数组就是一个容器数组定义格式:1.数据类型[] 变量名 = new 数据类型[数组长度] int[] arr = new int[5]; 2.数据类型[] 数组名 ...
- 剑指offer第二版面试题10:斐波那契数列(JAVA版)
题目:写一个函数,输入n,求斐波那契数列的第n项.斐波那契数列的定义如下: 1.效率很低效的解法,挑剔的面试官不会喜欢 使用递归实现: public class Fibonacci { public ...
- opencv bwlabel
int bwLabel(const Mat& imgBw, Mat& imgLabeled) { Mat imgClone = Mat(imgBw.rows + , imgBw.col ...
- certbot免费证书
yum install python-certbot-nginx 开启防火墙443端口 firewall-cmd --add-port=443/tcp --permanent 别忘了重启 firewa ...
- MySql 主从复制及深入了解
分享一个不错的mysql文章 https://segmentfault.com/a/1190000008942618
- python#父与子的编程之旅#第十四章
1. 为BankAccount 建立一个类定义.它应该有一些属性,包括账户名(一个字符串).账号(一个字符串或整数)和余额(一个浮点数),另外还要有一些方法显示余额.存钱和取钱. class Bank ...