首页 > 代码库 > 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类型的同步句柄,可以通过WaitOneWaitAnyWaitAll方法进行线程同步。这样就可以不用轮询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();        }        
View Code

(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();        }
View Code

(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();        }
View Code