.net多线程与异步小结
来源:互联网 发布:ubuntu windows双系统 编辑:程序博客网 时间:2024/05/17 08:25
A、Thread,分两种,实例时带入一个委托,System.Threading.ThreadStart是无参数委托,System.Threading.ParameterizedThreadStart是带参数委托,这两个委托都是现成的
不带参数
Thread thread=new Thread(ThreadStart start);
带参数
Thread thread=new Thread(ParameterizedThreadStart start);
不带参数例子: 在form的label上刷新当前时间
Thread thread = new Thread(new ThreadStart(() => { while (true) this.Invoke(new MethodInvoker(() => { label1.Text = DateTime.Now.ToString(); })); })); thread.Start();
带参数例子 ParameterizedThreadStart委托带一个object的形参,说明带啥参数都是可以的
Thread thread = new Thread(new ParameterizedThreadStart((s) => { while (true) this.Invoke(new MethodInvoker(() => { label1.Text = (string)s + DateTime.Now.ToString(); })); })); thread.Start("带参数");
B、ThreadPool,线程池允许在后台运行多个工作,而不需要为每个任务频繁地创建和销毁单独的线程,从而减少了开销。此类是一个静态类 其静态方法 public static bool QueueUserWorkItem(WaitCallback callBack);用于将方法排入队列以便执行。此方法在有线程池线程变得可用时执行。WaitCallback也是个带object形参的现成委托和ParameterizedThreadStart类似
例子:直接把匿名方法扔进去就开始运行了,只是要注意线程池的可用值,可用即执行。
ThreadPool.QueueUserWorkItem(new WaitCallback((s) => { while (true) this.Invoke(new MethodInvoker(() => { label1.Text = (string)s + DateTime.Now.ToString(); })); }), "带参数");
C、异步AsyncCallback 又是一个现成的委托,注意带入形参的类型是IAsyncResult,注意IAsyncResult这个接口下有个object AsyncState { get; }
例子:两个例子的区别只在AsyncState是什么?
1、
public partial class Form1 : Form { delegate void MyHandler(string s); public Form1() { InitializeComponent(); MyHandler handler = new MyHandler((s) => { for (int i = 0; i < 10000; i++) this.Invoke(new MethodInvoker(() => { label1.Text = s + i.ToString(); })); }); AsyncCallback callback = new AsyncCallback(MyCallBack); handler.BeginInvoke("带参数", callback , handler); //注意第三个object类型的参数,其实就是AsyncState,所以把handler放进去在回调里显式转换一下就是委托了 } public void MyCallBack(IAsyncResult ar) //回调函数,线程处理完执行的方法 { ((MyHandler)ar.AsyncState).EndInvoke(ar); } }
2、
public partial class Form1 : Form { delegate void MyHandler(string s); public Form1() { InitializeComponent(); MyHandler handler = new MyHandler((s) => { for (int i = 0; i < 10000; i++) this.Invoke(new MethodInvoker(() => { label1.Text = s + i.ToString(); })); }); AsyncCallback callback = new AsyncCallback(MyCallBack); handler.BeginInvoke("带参数", callback , "回调完毕"); //此处第三个参数把AsyncState用来传值(或者直接设为null),回调方法里就不一样 } public void MyCallBack(IAsyncResult ar) //回调函数,线程处理完执行的方法 { MyHandler handler = (MyHandler)((AsyncResult)ar).AsyncDelegate; handler.EndInvoke(ar); this.Invoke(new MethodInvoker(() => { label1.Text += ar.AsyncState; })); } }
D、由C联想到文件IO的异步、网络的异步,其实大同小异
文件IO异步例子
public partial class Form1 : Form { const int bufferSize = 10; byte[] data = new byte[bufferSize]; List<byte> totalData = new List<byte>(); AsyncCallback callback; public Form1() { InitializeComponent(); FileStream fs = new FileStream("Test.txt", FileMode.Open, FileAccess.Read, FileShare.Read, 10240, true); callback = new AsyncCallback(MyCallBack); fs.BeginRead(data, 0, bufferSize, callback, fs); //BeginRead背后的实现其实是这样的:ReadDelegate delegate2 = new ReadDelegate(this.Read); delegate2.BeginInvoke(buffer, offset, count, callback, state); 多么熟悉 } public void MyCallBack(IAsyncResult ar) { FileStream fs = (FileStream)ar.AsyncState; int bytesRead = fs.EndRead(ar); if (bytesRead > 0) { fs.BeginRead(data, 0, bufferSize, callback, fs); totalData.AddRange(data); Array.Clear(data, 0, bufferSize); } else //读完一起显示 { this.Invoke(new MethodInvoker(() => { label1.Text = Encoding.Default.GetString(totalData.ToArray()); })); fs.Close(); } } }
网络接收的例子
public partial class Form1 : Form { const int bufferSize = 4096; byte[] buffer = new byte[bufferSize]; AsyncCallback callback; public Form1() { InitializeComponent(); ThreadPool.QueueUserWorkItem(new WaitCallback((o) => { IPAddress ip = IPAddress.Parse("127.0.0.1"); TcpListener listener = new TcpListener(ip, 8888); listener.Start(); while (true) //循环处理,可以同时支持多个client { TcpClient client = listener.AcceptTcpClient(); NetworkStream stream = client.GetStream(); callback = new AsyncCallback(MyCallBack); stream.BeginRead(buffer, 0, bufferSize, callback, client);//最后一个参数把TcpClient放进去,回调中就可以分别处理不同的Client了 } })); } public void MyCallBack(IAsyncResult ar) { TcpClient client = (TcpClient)ar.AsyncState; //把TcpClient取出来,AsyncState真是好东西 NetworkStream stream = client.GetStream(); int bytesRead = stream.EndRead(ar); try { if (bytesRead > 0) //有数据 { this.Invoke(new MethodInvoker(() => { label1.Text += Encoding.Unicode.GetString(buffer, 0, bytesRead); })); Array.Clear(buffer, 0, buffer.Length); } stream.BeginRead(buffer, 0, bufferSize, callback, client); } catch (Exception) { if (stream != null) stream.Dispose(); client.Close(); } } }
为了方便上面程序调试给个发送数据的例子
static void Main(string[] args) { TcpClient client; try { client = new TcpClient(); client.Connect("localhost", 8888); while (true) { string msg = Console.ReadLine(); NetworkStream stream = client.GetStream(); byte[] buffer = Encoding.Unicode.GetBytes(msg); stream.Write(buffer, 0, buffer.Length); Console.WriteLine("发送: {0}", msg); } } catch (Exception ex) { Console.WriteLine(ex.Message); } }
E、BackgroundWorker 也是用来执行多线程任务的一个控件,其有三个事件,用起来比较优雅,也经常配合进度条使用,ReportProgress会触发ProgressChanged事件,从而实现进度刷新
BackgroundWorker worker = new BackgroundWorker(); worker.WorkerReportsProgress = true; //报告进度 worker.DoWork += (sender, e) => { for (int i = 0; i <= 10000; i++) this.Invoke(new MethodInvoker(() => { label1.Text = i.ToString(); worker.ReportProgress(i / 100, null); })); }; worker.RunWorkerCompleted += (sender, e) => { this.Invoke(new MethodInvoker(() => { label1.Text += "执行完毕"; })); }; worker.ProgressChanged += (sender, e) => { progressBar1.Style = ProgressBarStyle.Continuous; progressBar1.Value = e.ProgressPercentage; }; worker.RunWorkerAsync();
- .net多线程与异步小结
- .net异步与多线程
- NET多线程与异步编程
- C#.net同步异步SOCKET通信和多线程小结
- .net 异步编程小结
- 多线程与异步
- 多线程与异步
- 多线程与异步调用
- 多线程与异步加载
- 多线程与异步任务
- 多线程:同步与异步
- C#多线程与异步
- Swing与多线程-小结
- C#异步调用与多线程
- 异步与多线程的区别
- 异步与多线程的区别
- 异步与多线程的区别
- 多线程与异步的区别
- vc获取window版本
- 探索推荐引擎内部的秘密,第 2 部分: 深入推荐引擎相关算法 - 协同过滤
- windows编程经典书籍
- 使用J-Link启动海思3516最小系统
- My97DatePicker时间控件使用心得
- .net多线程与异步小结
- 静默安装功能的实现
- 赤壁赋
- 使用Block对POST异步操作的简单封装,NSURLConnection
- .net(C#)访问Oracle数据库的几种免安装组件的对比
- 二叉树的10个重要结论
- nginx upload module 的安装
- android 腾讯微博开发日记 day1
- Java内存参数配置