C#多線程代碼示例


using System;
using System.Threading;

namespace MultiThreadDemo
{
    class Program
    {
        public static void threadfunc()
        {
            try
            {
                Console.WriteLine("Child thread starts");
                Thread.Sleep(1000);
            }
            catch (ThreadAbortException / *ex* /)
            {
                Console.WriteLine("Thread abort!");
            }
        }

        static void Main(string[] args)
        {
            ThreadStart func = new ThreadStart(threadfunc);
            Thread th = new Thread(func);

            th.Start();
            Thread.Sleep(500);

            th.Abort();

            Console.ReadLine();
        }
    }
}
ThreadStart 無需傳參給線程函數時
using System;
using System.Threading;

// The ThreadWithState class contains the information needed for
// a task, and the method that executes the task.
//
public class ThreadWithState
{
    // State information used in the task.
    private string boilerplate;
    private int numberValue;

    // The constructor obtains the state information.
    public ThreadWithState(string text, int number)
    {
        boilerplate = text;
        numberValue = number;
    }

    // The thread procedure performs the task, such as formatting
    // and printing a document.
    public void ThreadProc()
    {
        Console.WriteLine(boilerplate, numberValue);
    }
}

// Entry point for the example.
//
public class Example
{
    public static void Main()
    {
        // Supply the state information required by the task.
        ThreadWithState tws = new ThreadWithState(
            "This report displays the number {0}.", 42);

        // Create a thread to execute the task, and then
        // start the thread.
        Thread t = new Thread(new ThreadStart(tws.ThreadProc));
        t.Start();
        Console.WriteLine("Main thread does some work, then waits.");
        //t.Join();
        //Console.WriteLine(
        //    "Independent task has completed; main thread ends.");
    }
}
// The example displays the following output:
//       Main thread does some work, then waits.
//       This report displays the number 42.
//       Independent task has completed; main thread ends.
ThreadStart 需傳參給線程函數時
using System;
using System.Threading;

// The ThreadWithState class contains the information needed for
// a task, the method that executes the task, and a delegate
// to call when the task is complete.
//
public class ThreadWithState
{
    // State information used in the task.
    private string boilerplate;
    private int numberValue;

    // Delegate used to execute the callback method when the
    // task is complete.
    private ExampleCallback callback;

    // The constructor obtains the state information and the
    // callback delegate.
    public ThreadWithState(string text, int number,
        ExampleCallback callbackDelegate)
    {
        boilerplate = text;
        numberValue = number;
        callback = callbackDelegate;
    }

    // The thread procedure performs the task, such as
    // formatting and printing a document, and then invokes
    // the callback delegate with the number of lines printed.
    public void ThreadProc()
    {
        Console.WriteLine(boilerplate, numberValue);
        Thread.Sleep(3000);
        if (callback != null)
            callback(1);
    }
}

// Delegate that defines the signature for the callback method.
//
public delegate void ExampleCallback(int lineCount);

// Entry point for the example.
//
public class Example
{
    public static void Main()
    {
        // Supply the state information required by the task.
        ThreadWithState tws = new ThreadWithState(
            "This report displays the number {0}.",
            42,
            new ExampleCallback(ResultCallback)
        );

        Thread t = new Thread(new ThreadStart(tws.ThreadProc));

        / *
            默認情況,在新開啟一個子線程的時候,他是前台線程,只有,將線程的IsBackground屬性設為true;他才是后台線程
            當子線程是前台線程,則主線程結束並不影響其他線程的執行,只有所有前台線程都結束,程序結束
            當子線程是后台線程,則主線程的結束,會導致子線程的強迫結束
         * /
        t.IsBackground = true;

        t.Start();
        Console.WriteLine("Main thread does some work, then waits.");
        t.Join();
        Console.WriteLine(
            "Independent task has completed; main thread ends.");
    }

    // The callback method must match the signature of the
    // callback delegate.
    //
    public static void ResultCallback(int lineCount)
    {
        Console.WriteLine(
            "Independent task printed {0} lines.", lineCount);
    }
}
// The example displays the following output:
//       Main thread does some work, then waits.
//       This report displays the number 42.
//       Independent task printed 1 lines.
//       Independent task has completed; main thread ends.
ThreadStart 需傳參給線程函數 + 需要接收線程中返回值,此時要傳入回調函數給線程函數
using System;
using System.Threading;

public class Work
{
    public static void Main()
    {
        // Start a thread that calls a parameterized static method.
        Thread newThread = new Thread(Work.DoWork);
        newThread.Start(42);

        // Start a thread that calls a parameterized instance method.
        Work w = new Work();
        newThread = new Thread(w.DoMoreWork);
        newThread.Start("The answer.");

        Console.ReadLine();
    }

    public static void DoWork(object data)
    {
        Console.WriteLine("Static thread procedure. Data='{0}'", data);
    }

    public void DoMoreWork(object data)
    {
        Console.WriteLine("Instance thread procedure. Data='{0}'", data);
    }
}
// This example displays output like the following:
//       Static thread procedure. Data='42'
//       Instance thread procedure. Data='The answer.'
ParameterizedThreadStart
using System;
using System.Threading;

public class Example
{
    static Thread thread1, thread2;

    public static void Main()
    {
        thread1 = new Thread(ThreadProc);
        thread1.Name = "Thread1";
        thread1.Start();

        thread2 = new Thread(ThreadProc);
        thread2.Name = "Thread2";
        thread2.Start();


        Console.ReadLine();
    }

    static TimeSpan waitTime = new TimeSpan(0, 0, 2);
    private static void ThreadProc()
    {
        Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
        if (Thread.CurrentThread.Name == "Thread1" &&
            thread2.ThreadState != ThreadState.Unstarted)
            //thread2.Join();
            //if (thread2.Join(2000))
            //if (thread2.Join(waitTime))
            if (thread2.Join(TimeSpan.FromSeconds(2)))
                Console.WriteLine("Thread2 has termminated.");
            else
                Console.WriteLine("The timeout has elapsed and Thread1 will resume.");

        Thread.Sleep(4000);
        Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
        Console.WriteLine("Thread1: {0}", thread1.ThreadState);
        Console.WriteLine("Thread2: {0}\n", thread2.ThreadState);
    }
}
// The example displays output like the following:
//       Current thread: Thread1
//       
//       Current thread: Thread2
//       
//       Current thread: Thread2
//       Thread1: WaitSleepJoin
//       Thread2: Running
//       
//       
//       Current thread: Thread1
//       Thread1: Running
//       Thread2: Stopped
Join 等待其它線程執行完,在此之前一直處於阻塞狀態
using System;
using System.Security.Permissions;
using System.Threading;

class ThreadInterrupt
{
    static void Main()
    {
        StayAwake stayAwake = new StayAwake();
        Thread newThread =
            new Thread(new ThreadStart(stayAwake.ThreadMethod));
        newThread.Start();

        Thread.Sleep(500);
        // The following line causes an exception to be thrown 
        // in ThreadMethod if newThread is currently blocked
        // or becomes blocked in the future.
        newThread.Interrupt();
        Console.WriteLine("Main thread calls Interrupt on newThread.");

        // Tell newThread to go to sleep.
        stayAwake.SleepSwitch = true;

        // Wait for newThread to end.
        newThread.Join();


        Console.WriteLine("Main thread .");
    }
}

class StayAwake
{
    bool sleepSwitch = false;

    public bool SleepSwitch
    {
        set { sleepSwitch = value; }
    }

    public StayAwake() { }

    public void ThreadMethod()
    {
        Console.WriteLine("newThread is executing ThreadMethod.");
        while (!sleepSwitch)
        {
            // Use SpinWait instead of Sleep to demonstrate the 
            // effect of calling Interrupt on a running thread.
            Thread.SpinWait(60000000);  // 只是讓CPU去執行一段沒有用的代碼。當時間結束之后繼續執行其它代碼,而不是重新參與CPU的競爭。
        }
        try
        {
            Console.WriteLine("newThread going to sleep.");

            // When newThread goes to sleep, it is immediately 
            // woken up by a ThreadInterruptedException.
            Thread.Sleep(Timeout.Infinite); // 是強制放棄CPU的時間片,然后重新和其他線程一起參與CPU的競爭。
        }
        catch (ThreadInterruptedException e)
        {
            Console.WriteLine("newThread cannot go to sleep - " +
                "interrupted by main thread.");
        }
    }
}
Interrupt 中斷Sleep操作
using System;
using System.Threading;

class Test
{
    public static void Main()
    {
        Thread newThread = new Thread(new ThreadStart(TestMethod));
        newThread.Start();
        Thread.Sleep(1000);

        // Abort newThread.
        Console.WriteLine("Main aborting new thread.");
        newThread.Abort("Information from Main.");  //可為異常類提供異常信息

        // Wait for the thread to terminate.
        newThread.Join();
        Console.WriteLine("New thread terminated - Main exiting.");
    }

    static void TestMethod()
    {
        try
        {
            while (true)
            {
                Console.WriteLine("New thread running.");
                Thread.Sleep(1000);
            }
        }
        catch (ThreadAbortException abortException)
        {
            Console.WriteLine((string)abortException.ExceptionState);
        }
    }
}
Abort 中斷線程
using System;
using System.Threading;

namespace InterlockedExchange_Example
{
    class MyInterlockedExchangeExampleClass
    {
        //0 for false, 1 for true.
        private static int usingResource = 0;

        private const int numThreadIterations = 5;
        private const int numThreads = 3;

        static void Main()
        {
            Thread myThread;
            Random rnd = new Random();

            for (int i = 0; i < numThreads; i++)
            {
                myThread = new Thread(new ThreadStart(MyThreadProc));
                myThread.Name = String.Format("Thread{0}", i + 1);

                //Wait a random amount of time before starting next thread.
                Thread.Sleep(rnd.Next(0, 1000));
                myThread.Start();
            }

            Console.ReadLine();
        }

        private static void MyThreadProc()
        {
            for (int i = 0; i < numThreadIterations; i++)
            {
                UseResource();

                //Wait 1 second before next attempt.
                Thread.Sleep(1000);
            }
        }

        //A simple method that denies reentrancy.
        static bool UseResource()
        {
            //0 indicates that the method is not in use.
            if (0 == Interlocked.Exchange(ref usingResource, 1))
            {
                Console.WriteLine("{0} acquired the lock", Thread.CurrentThread.Name);

                //Code to access a resource that is not thread safe would go here.

                //Simulate some work
                Thread.Sleep(500);

                Console.WriteLine("{0} exiting lock", Thread.CurrentThread.Name);

                //Release the lock
                Interlocked.Exchange(ref usingResource, 0);
                return true;
            }
            else
            {
                Console.WriteLine("   {0} was denied the lock", Thread.CurrentThread.Name);
                return false;
            }
        }
    }
}
Interlocked 為多線程共享的變量提供原子操作
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace WaitAndPulse
{
    public class LockMe
    {
    }

    class WaitPulse1
    {
        private int result = 0;
        private LockMe lM;

        public WaitPulse1()
        {
        }

        public WaitPulse1(LockMe l)
        {
            this.lM = l;
        }

        public void CriticalSection()
        {
            Monitor.Enter(this.lM);

            Console.WriteLine("WaitPulse1: Entered Thread "
                + Thread.CurrentThread.GetHashCode());

            //Thread.Sleep(1500);

            for (int i = 1; i <= 5; i++)
            {
                Monitor.Wait(this.lM);

                Console.WriteLine("WaitPulse1: WokeUp");
                Console.WriteLine("WaitPulse1: Result = "
                    + result++
                    + " ThreadID "
                    + Thread.CurrentThread.GetHashCode());

                Monitor.Pulse(this.lM);
            }
            Console.WriteLine("WaitPulse1: Exiting Thread "
                + Thread.CurrentThread.GetHashCode());

            Monitor.Exit(this.lM);
        }
    }

    class WaitPulse2
    {
        private int result = 0;
        private LockMe lM;

        public WaitPulse2()
        {
        }

        public WaitPulse2(LockMe l)
        {
            this.lM = l;
        }

        public void CriticalSection()
        {
            // 在指定對象上獲取排他鎖
            Monitor.Enter(this.lM);
          
            Console.WriteLine("WaitPulse2: Entered Thread "
                + Thread.CurrentThread.GetHashCode());

            for (int i = 1; i <= 5; i++)
            {
                // 通知等待隊列中的線程鎖定對象狀態的更改
                // 目的是為了讓另外一個線程中的Wait不阻塞
                Monitor.Pulse(this.lM);

                Console.WriteLine("WaitPulse2: Result = "
                    + result++
                    + " ThreadID "
                    + Thread.CurrentThread.GetHashCode());
               
                // 釋放對象上的鎖並阻止當前的線程,直到它重新獲取該鎖
                Monitor.Wait(this.lM);

                Console.WriteLine("WaitPulse2: WokeUp");
            }
            Console.WriteLine("WaitPulse2: Exiting Thread "
                + Thread.CurrentThread.GetHashCode());

            // 釋放指定對象上的排他鎖
            Monitor.Exit(this.lM);
        }
    }

    public class ClassForMain
    {
        public static void Main(string[] args)
        {
            LockMe l = new LockMe();

            WaitPulse1 e1 = new WaitPulse1(l);
            WaitPulse2 e2 = new WaitPulse2(l);

            Thread t1 = new Thread(new ThreadStart(e1.CriticalSection));
            t1.Start();

            Thread.Sleep(200);

            Thread t2 = new Thread(new ThreadStart(e2.CriticalSection));
            t2.Start();

            //Wait till the user enters something
            Console.ReadLine();
        }
    }
}
Monitor
//-------------------------------------------------------------------------------------
//  Monitor
//  線程優先順序: 【擁有鎖線程】> 【就緒隊列】> 【等待隊列】
//-------------------------------------------------------------------------------------

using System;
using System.Threading;
using System.Diagnostics;
using System.Collections;

public class ProgramMain
{
    const int MAX_LOOP_TIME = 10;
    private static Queue m_smpQueue = new Queue();
    private static object obj = new object();

    public class ThreadFunc
    {
        /// <summary>
        /// 將要處理的數據放入隊列
        /// </summary>
        public void ThreadAFunc()
        {
            int count = 0;
            lock(obj)
            {
                Monitor.Pulse(obj);
                while (count < MAX_LOOP_TIME)
                {
                    Trace.WriteLine("ThreadA WriteLine");
                    m_smpQueue.Enqueue(count);

                    // 等待ThreadB處理數據!
                    // (當前線程釋放同步鎖;當前線程轉入【等待隊列】,直到當前線程再次轉到【就緒隊列】並再次獲取鎖才繼續 否則一直阻塞)
                    Monitor.Wait(obj);
                    
                    // 讓【等待隊列】中的線程轉入【就緒隊列】(一旦當前線程不再擁有鎖,就緒隊列中的線程可以擁有鎖)
                    Monitor.Pulse(obj);

                    count++;
                }
            }
        }

        /// <summary>
        /// 處理隊列中數據
        /// </summary>
        public void ThreadBFunc()
        {
            lock (obj)
            {
                do
                {
                    if(m_smpQueue.Count > 0)
                    {
                        // 數據處理
                        int count = (int)m_smpQueue.Dequeue();
                        Console.WriteLine(count.ToString());
                        Trace.WriteLine("ThreadB WriteLine");
                        //Thread.Sleep(3000);
                    }
                    // 讓【等待隊列】中的線程轉入【就緒隊列】
                    Monitor.Pulse(obj);
                } while (Monitor.Wait(obj, 10000));   // 等待數據入隊列(當前線程釋放鎖)
            }
        }
    }

    public static void Main(string[] args)
    {
        ThreadFunc a = new ThreadFunc();

        Thread ta = new Thread(new ThreadStart(a.ThreadAFunc));
        Thread tb = new Thread(new ThreadStart(a.ThreadBFunc));

        ta.Start();
        tb.Start();

        //Console.ReadLine();
    }
}
Monitor (Wait、Pulse) 

 參考  C# Monitor的Wait和Pulse方法使用詳解


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM