首页 > 代码库 > C# 线程之间的同步
C# 线程之间的同步
1、通过Join方法,暂停当前线程
Thread secondThread = new Thread(new ThreadStart(ThreadMethod));
secondThread.Start();
...
secondThread.Join();
2、通过启动APM异步操作的方法,得到一个IAsyncResult对象,通过它有三种方法使得两个线程同步。
public interface IAsynResult
{
object AsyncState{get; }
WaitHandle AsyncWaitHandle{get; }
bool CompletedSynchronously{get; }
bool IsCompleted{get; }
}
实现这个接口的对象用来存储异步操作的状态信息,并提供一个异步对象以允许线程在操作完成时中止。
AsyncState:是一个只读的Object类型属性,表示在Begin方法中传递的用户自定义的参数对象。
AsyncWaitHandle:是一个WaitHandle类型的同步句柄,可以通过WaitOne,WaitAny,WaitAll方法进行线程同步。这样就可以不用轮询IsCompled状态直到操作结束。
CompletedSynchronously:很少用,一般返回false。
IsCompleted:bool类型,用于表示异步操作是否已经完成。
对于APM操作来说,必须使用End方法来结束异步操作,否则会造成资源的泄露。
(1)轮询方法
while(!result.IsCompleted)
{
Thread.Sleep(10);
}
private static void APM_4_1() { Console.WriteLine("主程序中!"); Console.WriteLine("线程的 Id: {0}", Thread.CurrentThread.ManagedThreadId); Console.WriteLine(); string path = "../../demo.log"; byte[] buffer = new byte[4096]; System.IO.FileStream fs = new System.IO.FileStream(path, System.IO.FileMode.Open); IAsyncResult result = fs.BeginRead(buffer, 0, 4096, delegate(IAsyncResult ar) { Console.WriteLine("第三步操作中。"); Console.WriteLine("线程的 Id: {0}", Thread.CurrentThread.ManagedThreadId); int length = fs.EndRead(ar); string message = System.Text.Encoding.UTF8.GetString(buffer, 0, length); Console.WriteLine(message); Console.WriteLine(); }, null); Console.WriteLine("第一步操作已经完成。现在主程序继续进行!"); Console.WriteLine("线程的 Id: {0}", Thread.CurrentThread.ManagedThreadId); Console.WriteLine(); // 等待第二个线程完成 while (!result.IsCompleted) { Thread.Sleep(10); } Console.WriteLine("注意,此时第三步操作已经完成,回车后结束程序。"); Console.WriteLine(); Console.ReadLine(); }
(2)使用WaitHandle等待第二个线程完成
private static void APM_4_2() { Console.WriteLine("主程序中!"); Console.WriteLine("线程的 Id: {0}", Thread.CurrentThread.ManagedThreadId); Console.WriteLine(); string path = "../../demo.log"; byte[] buffer = new byte[4096]; System.IO.FileStream fs = new System.IO.FileStream( path, System.IO.FileMode.Open, System.Security.AccessControl.FileSystemRights.Read, System.IO.FileShare.Read, 8, System.IO.FileOptions.Asynchronous); IAsyncResult result = fs.BeginRead(buffer, 0, 4096, null, null); Console.WriteLine("第一步操作已经完成。现在主程序继续进行!"); Console.WriteLine("线程的 Id: {0}", Thread.CurrentThread.ManagedThreadId); result.AsyncWaitHandle.WaitOne(); int length = fs.EndRead(result); string message = System.Text.Encoding.UTF8.GetString(buffer, 0, length); Console.WriteLine(message); Console.WriteLine(); Console.WriteLine("注意,此时第三步操作已经完成,回车后结束程序。"); Console.WriteLine(); Console.ReadLine(); }
(3)直接调用EndRead方法进入等待
private static void APM_4_3() { Console.WriteLine("主程序中!"); Console.WriteLine("线程的 Id: {0}", Thread.CurrentThread.ManagedThreadId); Console.WriteLine(); string path = "../../demo.log"; byte[] buffer = new byte[4096]; System.IO.FileStream fs = new System.IO.FileStream( path, System.IO.FileMode.Open, System.Security.AccessControl.FileSystemRights.Read, System.IO.FileShare.Read, 8, System.IO.FileOptions.Asynchronous); IAsyncResult result = fs.BeginRead(buffer, 0, 4096, null, null); Console.WriteLine("第一步操作已经完成。现在主程序继续进行!"); Console.WriteLine("线程的 Id: {0}", Thread.CurrentThread.ManagedThreadId); int length = fs.EndRead(result); string message = System.Text.Encoding.UTF8.GetString(buffer, 0, length); Console.WriteLine(message); Console.WriteLine(); Console.WriteLine("注意,此时第三步操作已经完成,回车后结束程序。"); Console.WriteLine(); Console.ReadLine(); }