using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp3
{
class Program
{
//线程工作集合
private static List Works = new List();
public delegate string MethodCaller(string name);//定义个代理
string name = "my name";//输入参数
private static object oLock = new object();
private static void Test2(object Count)
{
lock (oLock)
{
for (var i = 0; i < (int)Count; i++)
{
Console.WriteLine("后台线程计数" + i);
//Thread.Sleep(100);
}
}
}
static void Main(string[] args)
{
//MethodCaller mc = new MethodCaller(GetName);
//IAsyncResult result = mc.BeginInvoke(name, null, null);
//string myname = mc.EndInvoke(result);//用于接收返回值
//Console.Write("main start\r\n");
//Thread th = new Thread(ThreadMethod);//创建线程
//th.Start();//启动线程
//for (int i = 0; i < 10; i++)
//{
// if (i == 3) th.Suspend();
// if (i == 5) th.Resume();
// if (i == 7) th.Abort();
// Console.Write(i + "\r\n");
// Thread.Sleep(1000);
//}
//Console.WriteLine("thread end \r\n");
//Console.ReadKey();
/*
前言前面几节分别介绍了C#基础技术中的反射、特性、泛型、序列化、扩展方法、Linq to Xml等
这篇跟着来介绍C#的另一基础技术的使用。最近项目有点紧张,所以准备也不是特别充分。此片就主要从博主使用过的几种多线程的用法
从应用层main大概介绍下。文中观点都是博主个人的理解,如果不对望指正
1多线程:使用多个处理句柄同时对多个任务进行控制处理的一种技术,据博主的理解,多线程就是该应用的主线程任命其他多线程去协助它完成需要的共嗯那个
并且主线程和协助线程是独立进行的。不知道这样说好不好理解,后面慢慢在使用中会有更加详细的讲解
2多线程的使用
1最简单、最原始的使用方法:Thread oGetArgThread = new Thread(new ThreadStart(()=>{}));这种用法应该大多数人都使用过
参数为一个ThreadStart类型的委托。将ThreadStart转到定义可知
public delegate void ThreadStart()
说明主线程和后台线程是互相独立的。由系统调度资源去执行
如果这样那有人就要问了,如果我需要多线程执行的方法有参数或者有返回值或者既有参数又有返回值了。。。别着急我们来看
new Thread()的几个狗在函数
public Thread(ParameterizedThreadStart start)
{
public Thread(ThreadStart start)
public Thread(ParameterizedThreadStart start,int maxStackSize)
public Thread(ThreadStart start,int maxStackSize)
转到定义可知参数有两类,一类是无参无返回值的委托,另一类是有参无返回值的委托。对于有参数的委托使用方法
}
对于有参又有返回值的委托,很显然使用new Thread()这种方式是没有解决方案的。起始对于有参又有返回值的委托可以使用异步来实现
1Thread oGetArgThread = new Thread(new ThreadStart(Test))
oGetArgThread.Join();//主线程阻塞,等待分支线程运行结束,这一步看功能需求进行选择,主要为了多个进程达到同步的效果
2线程的优先级可以通过Thread对象Prioriy属性来设置,Priority属性对应一个枚举
public enum ThreadPriority
{
可以将System.Threading.Thread安排在具有任何其他优先级的线程之后
Lowest =0,
可以将System.Threading.Thread安排在具有Normal优先级的线程,在具有Lowest优先级的线程之前
BelowNormal =1,
可以将System.Threading.Thread安排在具有AboveNormal优先级的线程之后,在具有BelowNormal优先级的线程之前
Normal = 2,
可以将System.Threading.Thread安排在具有AboveNormal优先级的线程之后,在具有BelowNormal优先级的线程之前
AboveNormal =3,
可以将System.Threading.Thread安排在具有AboveNormal优先级的线程之后,在具有BelowNormal优先级的线程之前
Highest = 4
从0到4 优先级由低到高
关于多线程同时使用一个对象或资源的情况,也就是线程的资源共享,为了避免数据紊乱,一般采用.NET悲观锁lock的方式处理
Task方式使用多线程:这种方式一般用在需要循环处理某项业务并且需要得到处理后的结果
需要循环处理某项业务并且需要得到处理后的结果
需要循环处理某项业务并且需要得到处理后的结果
需要循环处理某项业务并且需要得到处理后的结果
需要循环处理某项业务并且需要得到处理后的结果
需要循环处理某项业务并且需要得到处理后的结果
需要循环处理某项业务并且需要得到处理后的结果
需要循环处理某项业务并且需要得到处理后的结果
需要循环处理某项业务并且需要得到处理后的结果
需要循环处理某项业务并且需要得到处理后的结果
需要循环处理某项业务并且需要得到处理后的结果
使用这种方式的时候需要注意一句var bdTmp = bd;这里使用要用到一个临时变量,要不然多个bd对象容易串数据
如果有兴趣可以调试看看。这种方法比较简单,就不多说了。当然Task对象的用法肯定远不止如此,还涉及到任务的调度等
复杂逻辑。博主对这些东西理解有限,就不讲解了
线程池的用法:一般用于考虑到服务器性能等问题,保证一个时间段内系统线程数量在一定范围,需要使用线程池的概念
大概用法如下
}
*/
//Thread oGetArgThread = new Thread(new ThreadStart(()=>
//{
// for (int i = 0; i < 1000; i++)
// {
// Console.WriteLine("后台线程计数"+i);
// }
//}));
List<Task> lstTaskBD = new List<Task>();
foreach (var bd in lstBoards)
{
var bdTmp = bd;//这里必须要用一个临时变量
var oTask = Task.Factory.StartNew(() =>
{
var strCpBdCmd = "rm - Rf" + bdTmp.Path + "/*;cp -R" + CombineFTPPaths(FTP_EMULATION_BD_ROOT,
"bd_correct" + "/*" + bdTmp.Path + "/");
oPlink.Run(bdTmp.EmulationServer.BigIP,bdTmp.EmulationServer.UserName,bdTmp.EmulationServer.Password,
strCpBdCmd);
Thread.Sleep(500);
});
lstTaskBD.Add(Task);
}
Task.WaitAll(lstTaskBD.ToArray());//等待所有线程都执行完
Thread oGetArgThread = new Thread(new ParameterizedThreadStart(Test));
oGetArgThread.IsBackground = true;
oGetArgThread.Start(100);
//for (int i = 0; i < 100000; i++)
//{
// Console.WriteLine("主线程计数"+i);
//}
Console.ReadKey();
//方式1:使用变量开关控制挂起线程和回复线程
//ThreadWorkItem wItem = null;
//Thread t = null;
//var threadNum = 2;
//for (int i = 0; i < threadNum; i++)
//{
// t = new Thread(o =>
// {
// var w = o as ThreadWorkItem;
// if (w == null)
// {
// return;
// }
// while (true)
// {
// if (!w.StopFlag)
// {
// Console.WriteLine("我是线程:" + Thread.CurrentThread.Name);
// }
// }
// });
//}
}
private static string GetName(string name)
{
return name;
}
private static void Test(object Count)
{
for (int i = 0; i < (int)Count; i++)
{
Console.WriteLine("后台线程计数"+i);
}
}
//static void ThreadMethod()
//{
// while (true)
// {
// Console.Write("thread\r\n");
// Thread.Sleep(500);
// }
}
}