C# 多线程 举例使用
使用多线程的几种方式
(1)不需要传递参数,也不需要返回参数
ThreadStart是一个委托,这个委托的定义为void ThreadStart(),没有参数与返回值。
/// <summary>
/// 连接
/// </summary>
/// <param name="host">服务器名称</param>
/// <param name="port">服务器端口</param>
public void Connect(string host, int port)
{
try
{
clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSock.Connect(host, port);
if (OnClientConn != null)
{
Session clientSession = new Session(clientSock);
OnClientConn(this, new NetEventArgs(clientSession));
}
Thread th = new Thread(new ThreadStart(ReceiveDataThread)); //也可简写为new Thread(ThreadMethod);
th.Start(); //启动线程
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
throw;
}
}
/// <summary>
/// 从服务器接收数据
/// </summary>
private void ReceiveDataThread()
{
while (clientSock != null)
{
try
{
Session clientSession = new Session(clientSock);
// Receives data from a bound Socket.
int bytesRec = clientSock.Receive(recvDataBuffer);
// Converts byte array to string
clientSession.Datagram = this.recvCoder.GetEncodingString(recvDataBuffer, bytesRec);
// Continues to read the data till data isn't available
while (clientSock.Available > 0)
{
bytesRec = clientSock.Receive(recvDataBuffer);
clientSession.Datagram += this.recvCoder.GetEncodingString(recvDataBuffer, bytesRec);
}
if(OnDataRecv!=null)
OnDataRecv(this, new NetEventArgs(clientSession));
}
catch (Exception ex)
{
DisConnect();
Debug.WriteLine(ex.Message);
}
}
}
(2)使用匿名方法(常用)
使用匿名方法启动线程可以有多个参数和返回值,而且使用非常方便!
/// <summary>
/// 弹出情报板消息框
/// </summary>
/// <param name="name">情报板的名称</param>
/// <param name="msg">要显示的信息</param>
private void _ucinfoboardview_OnShowAlert(string name, string msg)
{
this.ThreadMsnStart(new ThreadStart(delegate()
{
this.ThreadInfoBoard(name, msg);
}));
}
/// <summary>
/// 执行多线程弹窗
/// </summary>
/// <param name="threadstart">ThreadStart 委托</param>
private void ThreadMsnStart(ThreadStart threadstart)
{
Thread tst = new Thread(threadstart);
tst.Start();
}
/// <summary>
/// 线程入口 -- 情报板发布信息提示
/// </summary>
/// <param name="name">情报板的名称</param>
/// <param name="msg">情报板提示信息</param>
private void ThreadInfoBoard(string name, string msg)
{
ClsMsgForMSN tt = new ClsMsgForMSN();
tt.MyParentControl = this;
tt.InfoBoardName = name;
tt.InfoBoardMsg = msg;
//定义一个委托实例,该实例执行打开窗口代码
MethodInvoker mi = new MethodInvoker(tt.ShowInfoBoardMsg);
BeginInvoke(mi);
}
(3)使用委托开启多线程(多线程深入)
1、用委托(Delegate)的BeginInvoke和EndInvoke方法操作线程
BeginInvoke方法可以使用线程异步地执行委托所指向的方法。然后通过EndInvoke方法获得方法的返回值(EndInvoke方法的返回值就是被调用方法的返回值),或是确定方法已经被成功调用。
class Program
{
private delegate int NewTaskDelegate(int ms);
private static int newTask(int ms)
{
Console.WriteLine("任务开始");
Thread.Sleep(ms);
Random random = new Random();
int n = random.Next(10000);
Console.WriteLine("任务完成");
return n;
}
static void Main(string[] args)
{
NewTaskDelegate task = newTask;
IAsyncResult asyncResult = task.BeginInvoke(2000, null, null);
//EndInvoke方法将被阻塞2秒
int result = task.EndInvoke(asyncResult);
Console.WriteLine(result);
Console.Read();
}
}
2、使用IAsyncResult.IsCompleted属性来判断异步调用是否完成
class Program
{
private delegate int NewTaskDelegate(int ms);
private static int newTask(int ms)
{
Console.WriteLine("任务开始");
Thread.Sleep(ms);
Random random = new Random();
int n = random.Next(10000);
Console.WriteLine("任务完成");
return n;
}
static void Main(string[] args)
{
NewTaskDelegate task = newTask;
IAsyncResult asyncResult = task.BeginInvoke(2000, null, null);
//等待异步执行完成
while (!asyncResult.IsCompleted)
{
Console.Write("*");
Thread.Sleep(100);
}
// 由于异步调用已经完成,因此, EndInvoke会立刻返回结果
int result = task.EndInvoke(asyncResult);
Console.WriteLine(result);
Console.Read();
}
}
3、使用WaitOne方法等待异步方法执行完成
WaitOne的第一个参数表示要等待的毫秒数,在指定时间之内,WaitOne方法将一直等待,直到异步调用完成,并发出通知,WaitOne方法才返 回true。当等待指定时间之后,异步调用仍未完成,WaitOne方法返回false,如果指定时间为0,表示不等待,如果为-1,表示永远等待,直到 异步调用完成。
class Program
{
private delegate int NewTaskDelegate(int ms);
private static int newTask(int ms)
{
Console.WriteLine("任务开始");
Thread.Sleep(ms);
Random random = new Random();
int n = random.Next(10000);
Console.WriteLine("任务完成");
return n;
}
static void Main(string[] args)
{
NewTaskDelegate task = newTask;
IAsyncResult asyncResult = task.BeginInvoke(2000, null, null);
//等待异步执行完成
while (!asyncResult.AsyncWaitHandle.WaitOne(100, false))
{
Console.Write("*");
}
int result = task.EndInvoke(asyncResult);
Console.WriteLine(result);
Console.Read();
}
}
4、使用回调方式返回结果
要注意的是“my.BeginInvoke(3,300, MethodCompleted, my)”,BeginInvoke方法的参数传递方式:
前面一部分(3,300)是其委托本身的参数。
倒数第二个参数(MethodCompleted)是回调方法委托类型,他是回调方法的委托,此委托没有返回值,有一个IAsyncResult类型的参数,当method方法执行完后,系统会自动调用MethodCompleted方法。
最后一个参数(my)需要向MethodCompleted方法中传递一些值,一般可以传递被调用方法的委托,这个值可以使用IAsyncResult.AsyncState属性获得。
class Program
{
private delegate int MyMethod(int second, int millisecond);
//线程执行方法
private static int method(int second, int millisecond)
{
Console.WriteLine("线程休眠" + (second * 1000 + millisecond) + "毫秒");
Thread.Sleep(second * 1000 + millisecond);
Random random = new Random();
return random.Next(10000);
}
//回调方法
private static void MethodCompleted(IAsyncResult asyncResult)
{
if (asyncResult == null || asyncResult.AsyncState == null)
{
Console.WriteLine("回调失败!!!");
return;
}
int result = (asyncResult.AsyncState as MyMethod).EndInvoke(asyncResult);
Console.WriteLine("任务完成,结果:" + result);
}
static void Main(string[] args)
{
MyMethod my = method;
IAsyncResult asyncResult = my.BeginInvoke(3,300, MethodCompleted, my);
Console.WriteLine("任务开始");
Console.Read();
}
}
5、其他组件的BeginXXX和EndXXX方法
在其他的.net组件中也有类似BeginInvoke和EndInvoke的方法,如System.Net.HttpWebRequest类的BeginGetResponse和EndGetResponse方法。其使用方法类似于委托类型的BeginInvoke和EndInvoke方法,例如:
class Program
{
//回调函数
private static void requestCompleted(IAsyncResult asyncResult)
{
if (asyncResult == null || asyncResult.AsyncState==null)
{
Console.WriteLine("回调失败");
return;
}
HttpWebRequest hwr = asyncResult.AsyncState as HttpWebRequest;
HttpWebResponse response = (HttpWebResponse)hwr.EndGetResponse(asyncResult);
StreamReader sr = new StreamReader(response.GetResponseStream());
string str = sr.ReadToEnd();
Console.WriteLine("返回流长度:"+str.Length);
}
static void Main(string[] args)
{
HttpWebRequest request =
(HttpWebRequest)WebRequest.Create("http://www.baidu.com");
//异步请求
IAsyncResult asyncResult = request.BeginGetResponse(requestCompleted, request);
Console.WriteLine("任务开始");
Console.Read();
}
}
C# 多线程 举例使用的更多相关文章
- python之多线程举例
# 多线程举例 from threading import Thread from threading import current_thread class messager(Thread): de ...
- python多线程举例
Python中使用线程有两种方式:函数或者用类来包装线程对象. 1. 函数式:调用thread模块中的start_new_thread()函数来产生新线程.如下例: import time ...
- c++的多线程和多进程
一.多进程和多线程对比 多进程:进程不止一个,开销比较大,通信方式比较复杂(可以用过管道.文件.消息队列进行通信),维护成本不高. 多线程:利用共享内存的方式进行指令的执行,开销比较低,但是维护起来比 ...
- Java:多线程
创建线程的方式有两种: 第一种:使用线程类Thread或者继承它的子类创建线程对象 第二种:定义接口类实现接口Runnable创建线程对象 多线程的好处:可以整合资源,提高系统资源的利用率 多线程中提 ...
- 多线程&多进程解析:Python、os、sys、Queue、multiprocessing、threading
当涉及到操作系统的时候,免不了要使用os模块,有时还要用到sys模块. 设计到并行程序,一般开单独的进程,而不是线程,原因是python解释器的全局解释器锁GIL(global interpreter ...
- java 多线程总结篇4——锁机制
在开发Java多线程应用程序中,各个线程之间由于要共享资源,必须用到锁机制.Java提供了多种多线程锁机制的实现方式,常见的有synchronized.ReentrantLock.Semaphore. ...
- threading示例
多线程举例: import time import threading def worker(): print ("hello.Kamil") time.sleep(1)#等待一秒 ...
- socket_server源码剖析、python作用域、IO多路复用
本节内容: 课前准备知识: 函数嵌套函数的使用方法: 我们在使用函数嵌套函数的时候,是学习装饰器的时候,出现过,由一个函数返回值是一个函数体情况. 我们在使用函数嵌套函数的时候,最好也这么写. def ...
- Java 面试题:百度前200页都在这里了
基本概念 操作系统中 heap 和 stack 的区别 什么是基于注解的切面实现 什么是 对象/关系 映射集成模块 什么是 Java 的反射机制 什么是 ACID BS与CS的联系与区别 Cookie ...
随机推荐
- 《算法导论》——随机化快排RandomizedQuickSort
今日算法:随机化快排RandomizedQuickSort 基础工作swap交换和partition分治 /* *交换数组的两个元素 *fromIndex和toIndex为要交换的两个元素的索引 */ ...
- JavaScript 的基础学习(一)
JavaScript概述 JavaScript的历史 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名ScriptEase.( ...
- windows共享文件夹权限设置
权限设置及更改,最好在右键属性里面, 在计算机管理,共享文件夹->共享里面修改,有时候会不生效. windows的凭据修改,在用户注销后才会生效.
- __getitem__ __setitem__ __delitem__ 使用
#__getitem__ __setitem__ __delitem__运行设置key value值了class fun: def __init__(self): print('test') def ...
- 【java】String类常见操作
秋招做题需要,总结String类常用api如下: 简单的:str.length().str.isEmpty().str.split(“;”)切割 1.字符串反转:借助StringBuilder/Str ...
- 2017-11-03 Fr OCT 球体积的导数为球表面积
上学期学立体几何时注意到这一点.去问林老师,没听明白(写完笔记后发现林老师讲得是对的,惭愧).今天下午考历史的时候突然想起来. 除了球体积的导数为球表面积外,还注意到圆体积的导数为圆周长.今天中午看w ...
- python中安装request模块
使用命令行(cmd)进入到python安装目录下的Scripts文件夹(也可以先进入目标文件夹然后在文件路径上打开cmd回车即可) 在命令行中输入pip install requests,等待安装完成 ...
- Linux Tomcat安装部署项目
一.上传Tomcat服务器
- day43 多表查询和pymysql
复习 增删改查全语法 # 增 insert into db1.t1(字段2, 字段1, ..., 字段n)|省略 values (值2, 值1, ..., 值n)|(值1, 值2, ..., 值n)[ ...
- oracle 新增并返回新增的主键
oracle 的insert into 语句需要返回新增的主键的时候,可以使用一下insert 语法: insert into ims.t_bank_inquire_results (t_date,l ...