Threading in C#
来源:互联网 发布:ubuntu获取root权限 编辑:程序博客网 时间:2024/05/29 16:56
Threading in C#
线程,很复杂的一个东西。没有写过相关的代码,没有发言权。
所以只了解一下CLR下线程的基本知识点。
一、线程基本概念
1.CLR为每个线程保留独立的内存栈,从而分离各个线程的局部变量。
2.各个线程可以共享静态变量,以及所引用的同一个类实例的成员。
3.线程一旦结束,就不能再被执行了。
4.传递参数给线程。大概有三种方式:
A.使用ParameterizedThreadStart
public delegate void ParameterizedThreadStart(object obj);
static void Main()
{
Thread t = new Thread(new ParameterizedThreadStart(Go));
t.Start(true);
}
static void Go(object b)
{
bool v = (bool)b;
}
这种方式只能传一个参数。
B.使用匿名代理,间接调用其他方法
static void Main()
{
Thread t = new Thread(delegate() { LocalFunc("local function"); }
t.Start();
}
static void LocalFunc(string text) { Console.WriteLine(text);}
这种方式可以传任意个数的参数。
但是这种方式下,参数的传递不是在Start(),而是在callback里。这样参数就有可能在Start()之前被任意篡改。
static void Main()
{
string text = "Initial";
Thread t = new Thread(delegate() { LocalFunc(text); }
text = "Changed";
t.Start();
}
所以最好把要传递的参数设置为常量。(第一种方式和第三种方式其实都存在这种问题。)
C.代理方法使用类实例方法,把类实例的成员变量作为参数。
static void Main()
{
ClassA a = new ClassA();
a.size = 100;
Thread t = new Thread(a.Test());
t.Start();
}
class ClassA
{
public int size = 0;
public void Test()
{
Console.WriteLine(size.toString());
}
}
5.可以给线程的名字赋值,但是只能赋值一次。赋值多于一次会发生Exception。
6.线程分为Foreground(前台)和Background(后台)两种。
线程默认被创建为Foreground。
对于程序来说,当所有的Foreground线程结束了,那么这个程序也就结束了,即使还有Background线程在运行。因此 Background线程上的finally代码并不一定能在程序退出之前执行(所以要使用join方法阻止主线程的直接退出)。
7.有时候我们发现,windows程序有时候显示已经关闭,但是在process列表里还能看到。这就是因为windows form的主线程虽然 已经结束,但是还有其他的Foreground的线程仍在运行。
8.异常处理
Application.ThreadException,这个事件可以捕获到主线程上在windows消息队列建立起来以后的所有异常。但是无法捕获到其他线程上的异常。
AppDomain.UnhandledException,这个事件可以捕获到AppDomain上所有线程上的异常,但是它无法阻止程序的crash。因此对于一个production,应该在每个线程的入口点添加异常处理,避免production上出现crash。
9.Thread.Sleep(0)
Sleep(int millionsecond)是指放弃cpu一段时间。Sleep(0)并不是不放弃cpu,实际上Sleep(0)还是要放弃cpu,虽然时间很短,但是足够其他alive的线程获得cpu的时间片。
10.Join(int timeout)
Join方法可以block当前线程从而等待另外一个线程。有种说法:
JOin虽然block,但是它不影响消息队列的正常运行;Sleep()则会将消息队列挂起。
但是我做了个测试好像都会把消息队列挂起来。
11.ThreadPool中的所有线程都是Background线程。
二、EventWaitHandle, Mutext和Semaphore都继承自WaitHandle。他们都可以用来做多线程的同步,并且他们都支持跨进程的同步。 1.AutoResetEvent vs. ManualResetEvent
这两个都是EventWaitHandle的子类。都可以用来lock某个线程。他们只是Reset的方式区别不同:
AutoResetEvent在每次Set后,会自动Reset,从而保证每次只能有1个线程被唤醒。
ManualResetEvent则在每次Set后,保持信号为被通知,直到被手动的Reset,从而可以每次唤醒多个线程。
2.Mutex
Mutex其实就是个lock,只是它支持跨进程的lock。它最常用的方式是保证每个操作系统上只能运行某一个程序的实例。
class OneAtATimePlease
{
// Use a name unique to the application (eg include your company URL)
static Mutex mutex = new Mutex (false, "oreilly.com OneAtATimeDemo");
static void Main()
{
// Wait 5 seconds if contended – in case another instance
// of the program is in the process of shutting down.
if (!mutex.WaitOne (TimeSpan.FromSeconds (5), false))
{
Console.WriteLine ("Another instance of the app is running. Bye!");
return;
}
try
{
Console.WriteLine ("Running - press Enter to exit");
Console.ReadLine();
}
finally { mutex.ReleaseMutex(); }
}
}
只要在Mutex初始化时给Mutex一个name,它就可以被跨进程使用了。因为Mutex只能被一个线程占用,直到它被release。
如果创建Mutext的程序还在运行,那么当另外一个程序调用waitone时就会得到false。
3。Semaphore
信号量,是更高级的Mutex,因为它可以规定可以lock的线程的个数。
class SemaphoreTest
{
static Semaphore s = new Semaphore (3, 3); // Available=3; Capacity=3
static void Main()
{
for (int i = 0; i < 10; i++) new Thread (Go).Start();
}
static void Go()
{
while (true)
{
s.WaitOne();
Thread.Sleep (100); // Only 3 threads can get here at once
s.Release();
}
}
}
上面的程序可以保证只有3个线程可以同时运行。如果用WaitHandle实现就复杂了。
- Threading in C#
- Threading in C#
- Threading in C#
- Threading in C#
- Threading in C#
- Threading in C# ,phase 1
- Threading in C# , phase 4
- [coding] Threading differences in C# and Java
- Threading in C# 起步篇1
- C# Multi-Threading In A GUI Environment
- Threading in C#, phase3
- Threading in Python
- Threading in Android
- C# Threading Handbook
- Threading in .Net and WinForms
- Threading and latency in x264
- Threading in C#, phase 2
- Future of threading in Ogre
- 生活日历_第一篇
- 人生简单道理
- 用RSS聚合方法整合分布的企业数据
- 100青涩语录节选
- 2008年大量中国企业将开始局部性实施SOA
- Threading in C#
- Web2.0互联网泡沫已经延续至中国
- 需求分析(软件工程第三章)
- 用C#创建Windows服务(Windows Services)
- 毕业设计的设计部分笔记2
- 谷歌工具不是威胁 它不懂企业需求
- Happy
- SVG引擎开发1
- VS2005 VS2008新建网站和新建项目里选Web应用程序区别