1.  Thread类

C#多线程编程中Thread类需要包含名称空间System.Threading。

class Program
{
static void Main(string[] args)
{
Thread thread01 = new Thread(ThreadTask01);
thread01.Start();
// thread01.Join(); for (int i = 0; i < 5; i++)
{
Console.WriteLine("Thread Main is working !");
Thread.Sleep(20);
} Console.ReadKey(); }
static void ThreadTask01()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Thread task one is working !");
Thread.Sleep(20);
}
}
}

输出:

Start不会阻塞主线程,如果加入Join,则会阻塞主线程的执行,直到子线程执行完成才把控制权交还给主流程,但是各个子线程之间的并行执行不受Join影响。上例中加入Join的输出:

多个线程同时访问一个公共字段时,容易引起线程安全问题,C#中使用关键字lock保证数据的安全性和同步:

class Program
{
//static readonly object locker = new object();
static int TotalNum = 100; static void Main(string[] args)
{
Thread thread01 = new Thread(ThreadTask01);
Thread thread02 = new Thread(ThreadTask02);
thread01.Start();
thread02.Start(); Console.ReadKey(); }
static void ThreadTask01()
{
while (TotalNum > 0)
{
Console.WriteLine(TotalNum);
TotalNum--;
Thread.Sleep(10);
}
} static void ThreadTask02()
{
while (TotalNum > 0)
{
Console.WriteLine(TotalNum);
TotalNum--;
Thread.Sleep(10);
}
}
}

输出异常,中间有重复输出的数字:

添加lock:

class Program
{
static readonly object locker = new object();
static int TotalNum = 100; static void Main(string[] args)
{
Thread thread01 = new Thread(ThreadTask01);
Thread thread02 = new Thread(ThreadTask02);
thread01.Start();
thread02.Start(); Console.ReadKey(); }
static void ThreadTask01()
{
while (TotalNum > 0)
{
lock (locker)
{
Console.WriteLine(TotalNum);
TotalNum--;
}
Thread.Sleep(10);
}
} static void ThreadTask02()
{
while (TotalNum > 0)
{
lock (locker)
{
Console.WriteLine(TotalNum);
TotalNum--;
}
Thread.Sleep(10);
}
}
}

输出正常:

2. ParameterThreadStart委托

ParameterThreadStart委托定义为 void ParameterizedThreadStart(Object state)。

class Program
{
static int totalNum = 10;
static void Main(string[] args)
{
ParameterizedThreadStart thread01 = new ParameterizedThreadStart(ThreadTask01);
Thread thread = new Thread(thread01);
thread.Start(totalNum);
Console.ReadKey(); }
static void ThreadTask01(object obj)
{
for (int i = 0; i < Convert.ToInt32(obj); i++)
{
Console.WriteLine(i);
Thread.Sleep(10);
}
}
}

3. 匿名方法

匿名方法启动多线程是使用Thread类的另一种更加灵活的方法。

class Program
{
static void Main(string[] args)
{
ThreadStart threadStart = new ThreadStart(delegate ()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Thread one is working!");
}
});
Thread thread = new Thread(threadStart);
thread.Start();//多线程启动匿名方法
//等待线程结束
while (thread.ThreadState != ThreadState.Stopped)
{
Thread.Sleep(10);
}
Console.ReadKey();
} }

4. Delegate委托

委托是一种比较高级的多线程方法,可以传入参数和获取返回值,还可以查询异步操作是否完成。

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秒 //使用WaitOne阻塞主线程,直到子线程完成操作
while (!asyncResult.AsyncWaitHandle.WaitOne(100, false))
{
Console.Write("-");
} while (!asyncResult.IsCompleted) //查询线程是否完成
{
Console.Write("*");
Thread.Sleep(100);
}
int result = task.EndInvoke(asyncResult);
Console.WriteLine(result);
Console.Read();
}
}

C#常用多线程方法的更多相关文章

  1. .net学习之多线程、线程死锁、线程通信 生产者消费者模式、委托的简单使用、GDI(图形设计接口)常用的方法

    1.多线程简单使用(1)进程是不执行代码的,执行代码的是线程,一个进程默认有一个线程(2)线程默认情况下都是前台线程,要所有的前台线程退出以后程序才会退出,进程里默认的线程我们叫做主线程或者叫做UI线 ...

  2. 六种多线程方法解决UI线程堵塞

    http://blog.csdn.net/oyi319/article/details/6851371 一.六种多线程方法 .NET Framework2.0框架提供了至少4种方式实现多线程,它们是& ...

  3. WebAPi添加常用扩展方法及思维发散

    前言 在WebAPi中我们通常需要得到请求信息中的查询字符串或者请求头中数据再或者是Cookie中的数据,如果需要大量获取,此时我们应该想到封装一个扩展类来添加扩展方法,从而实现简便快捷的获取. We ...

  4. StringUtils中的常用的方法

    org.apache.commons.lang.StringUtils中常用的方法,这里主要列举String中没有,且比较有用的方法: 1. 检查字符串是否为空: static boolean isB ...

  5. JOptionPane类提示框的一些常用的方法

    JOptionPane类提示框的一些常用的方法 XMLOracleSwing 最近在做swing程序中遇到使用消息提示框的,JOptionPane类其中封装了很多的方法. 很方便的,于是就简单的整理了 ...

  6. 常用js方法

    function dateGetter(name, size, offset, trim) { offset = offset || 0; return function (date) { var v ...

  7. jQuery操作Table tr td常用的方法

    虽然现在DIV+CSS进行页的布局大行其道,但是很多地方使用table还是有很多优势,用table展示数据是比较方便的,下面汇总了jQuery操作Table tr td常用的方法,熟记这些操作技巧,下 ...

  8. iOS常用公共方法

      iOS常用公共方法 字数2917 阅读3070 评论45 喜欢236 1. 获取磁盘总空间大小 //磁盘总空间 + (CGFloat)diskOfAllSizeMBytes{ CGFloat si ...

  9. org.apache.commons.lang.StringUtils中常用的方法

    org.apache.commons.lang.StringUtils中常用的方法,这里主要列举String中没有,且比较有用的方法: 1. 检查字符串是否为空: static boolean isB ...

随机推荐

  1. 【习题 5-8 UVA - 230】Borrowers

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 用map+set写个模拟就好. 3个区域 书架.桌子.别人的手上. 其中前两个区域的书都能借出去. [代码] #include &l ...

  2. shiro 静态页面资源不显示 解决方案(转)

    最近做一个ssm+shiro的框架整和 不加shiro之前ssm中css和图片显示正常.加上以后无法显示. 解决方案: shiro有静态资源过滤. 配置资源匿名访问即可 <property na ...

  3. POJ 1833 生成排列

    题目链接:POJ 1833 /************************************ * author : Grant Yuan * time : 2014/10/19 16:38 ...

  4. 【t086】防护伞

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 据说2012的灾难和太阳黑子的爆发有关.于是地球防卫小队决定制造一个特殊防护伞,挡住太阳黑子爆发的区域 ...

  5. [PostgreSQL] Ensure Uniqueness in Postgres

    Let’s say we have a bank. Our bank wants to give each account for each user a unique name, for insta ...

  6. 如何用Swift创建一个复杂的加载动画

    现在在苹果应用商店上有超过140万的App,想让你的app事件非常具有挑战的事情.你有这样一个机会,在你的应用的数据完全加载出来之前,你可以通过一个很小的窗口来捕获用户的关注. 没有比这个更好的地方让 ...

  7. 【30.93%】【codeforces 558E】A Simple Task

    time limit per test5 seconds memory limit per test512 megabytes inputstandard input outputstandard o ...

  8. jquery-11 jquery中的事件切换如何实现

    jquery-11 jquery中的事件切换如何实现 一.总结 一句话总结:事件切换hover()和toggle()函数.参数两个,都是函数,依次执行两个函数. 1.如何实现单击切换图片? 用togg ...

  9. 使用Html5开发Android和iOS应用:HBuilder、Html5Plus、MUI

    活动主题:五一巨献,问答有礼,105QB送给IT互联网界的劳动人民活动时间:4月30日晚上10点~5月2日晚上10点网址: http://ask.jiutianniao.com  2014年的时候,就 ...

  10. MS SQL Server的STRING_SPLIT和STRING_AGG函数

    在较新版本的SQL中,出现有2个函数,STRING_SPLIT和STRING_AGG,前者是把带有分隔的字符串转换为表,而后者却是把表某一表转换为以某种字符分隔的字符串. 如下面: DECLARE @ ...