精通C#---多线程,并行,异步编程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/x13262608581/article/details/82286203

1.

// AppDomain ad = Thread.GetDomain();
// Context ctx = Thread.CurrentContext;

2.

public delegate int BinaryOp(int x, int y);

// 内部实现
public sealed class BinaryOp : System.MulticastDelegate
{
    public BinaryOp(object target, uint functionAddress);
    public int Invoke(int x, int y);
    public IAsyncResult BeginInvoke(int x, int y, AsyncCallback cb, object state);
    public int EndInvoke(IAsyncResult result);
}

public interface IAsyncResult
{
    object AsyncState { get; }
    WaitHandle AysncWaitHandle { get; }
    bool CompletedSynchronously { get; }
    bool IsCompleted { get; }
}

// AsyncCallback遵循以下模式
void FunName(IAsyncResult itfAR);

namespace SyncDelegateReview
{
    public delegate int BinaryOp(int x, int y);
    class Program
    {
        static void Main()
        {
            Console.WriteLine("Main() invoked on thread {0}.", Thread.CurrentThread.ManagedThreadId);
            BinaryOp b = new BinaryOp(Add);
            int answer = b(10, 10);
            Console.WriteLine("Doing more work in Main()");
            Console.WriteLine("10 + 10 is {0}.", answer);
            Console.ReadLine();
        }

        static int Add(int x, int y)
        {
            Console.WriteLine("Add() invoked on thread {0}.", Thread.CurrentThread.ManagedThreadId);
            Thread.Sleep(5000);
            return x+y;
        }

        static void Main2()
        {
            BinaryOp b = new BinaryOp(Add);
            IAsyncResult itfAR = b.BeginInvoke(10, 10, null, null);
            Console.WriteLine("Doing more work in main");

            // 直到异步调用完成,此线程才能继续
            int answer = b.EndInvoke(itfAR);
            Console.WriteLine("10 + 10 is {0}", answer);
        }

        // 改进版本
        static void Main3()
        {
            BinaryOp b = new BinaryOp(Add);
            IAsyncResult itfAR = b.BeginInvoke(10, 10, null, null);
            while(!itfAR.IsCompleted)
            {
                Console.WriteLine("Doing more work in Main");
                Thread.Sleep(1000);
            }

            int answer = b.EndInvoke(itfAR);
        }

        // 改进版本:次线程在任务完成时主动通知调用线程
    }
}

// 改进版本,次线程完成任务,主调调用 异步开始时的回调函数

namespace AsyncCallbackDelegate
{
    public delegate int BinaryOp(int x, int y);
    class Program
    {
        private static bool isDone = false;
        static void Main()
        {
            Console.WriteLine("Main() invoked on thread {0}", Thread.CurrentThread.ManagedThreadId);
            BinaryOp b = new BinaryOp(Add);
            IAysncResult itfAR = b.BeginInvoke(10, 10, new AsyncCallback(AddComplete), null);

            while(!isDone)
            {
                Thread.Sleep(1000);
                Console.WriteLine("Working...");
            }

            Console.ReadLine();
        }

        static int Add(int x, int y)
        {
            //Thread.CurrentThread.ManagedThreadId
            Thread.Sleep(5000);
            return x+y;
        }

        static void AddComplete(IAsyncResult itfAR)
        {
            // Thread.CurrentThread.ManagedThreadId
            Console.WriteLine("Your addition is complete");
            isDone = true;
        }

        // 改进后的AddComplete
        static void AddComplete(IAsyncResult itfAR)
        {
            // Thread.CurrentThread.ManagedThreadId
            Console.WriteLine("Your addition is complete");

            AsyncResult ar = (AsyncResult)itfAR;
            // 获取在另一线程中的触发本线程执行的委托对象
            BinaryOp b = (BinaryOp)ar.AsyncDelegate;
            Console.WriteLine("10+10 is {0}", b.EndInvoke(itfAR));
            isDone = true;
        }
    }
}


// 异步方法调用,携带额外参数版本
static void Main()
{
    ...
    IAsyncResult itfAR = b.BeginInvoke(10, 10, new AsyncCallback(AddComplete), "Main thanks you for adding these numbers.");
    ...
}

static void AddComplete(IAsyncResult itfAR)
{
    ...
    string msg = (string)itfAR.AysncState;
    Console.WriteLine(msg);
    isDone = true;
}

3.System.Threading

Interlocked
Monitor
Mutex
ParameterizedThreadStart
Semaphore
Thread
ThreadPool
ThreadPriority
ThreadStart
ThreadState
Timer
TimerCallback


System.Threading.Thread
CurrentContext
CurrentThread
GetDomain/GetDomainID
Sleep

IsAlive
IsBackground
Name
Priority
ThreadState
Abort
Interrupt
Join
Resume
Start
Suspend

static void Main()
{
    Thread primaryThread = Thread.CurrentThread;
    primaryThread.Name = "ThePrimaryThread";
    // Thread.GetDomain().FriendlyName
    // Thread.CurrentContext.ContextID
    // primaryThread.Name
    // primaryThread.IsAlive
    // primaryThread.Priority
    // primaryThread.ThreadState
}

4.手工创建次线程
创建一个方法作为新线程的入口点
创建一个ParameterizedThreadStart/ThreadStart委托,把上一步所定义方法的地址传给委托的构造函数。
创建一个Thread对象,把ParameterizedThreadStart/ThreadStart委托作为构造函数参数
建立任意初始化线程的特性
调用Thread.Start方法

public class Printer
{
    public void PrintNumbers()
    {
        for(int _i = 0; _i < 10; _i++)
        {
            Thread.Sleep(2000);
        }
    }

    static void Main()
    {
        string threadCount = Console.ReadLine();
        Thread primaryThread = Thread.CurrentThread;
        primaryThread.Name = "Primary";
        // Thread.CurrentThread.Name
        Printer p = new Printer();
        switch(threadCount)
        {
            case "2":
                {
                    Thread backgroundThread = new Thread(new ThreadStart(p.PrintNumbers));
                    backgroundThread.Name = "Secondary";
                    backgroundThread.Start();
                }
                break;

            case "1":
                {
                    p.PrintNumbers();
                }
                break;

            default:
                {
                    goto case "1";
                }
        }

        MessageBox.Show("xxx");
        Console.ReadLine();
    }
}

////////////参数化版本
class AddParams
{
    public int a, b;
    public AddParams(int numb1, int numb2)
    {
        a = numb1;
        b = numb2;
    }
}

class Program
{
    static void Add(object data)
    {
        if(data is AddParams)
        {
            AddParams ap = (AddParams)data;
            // ap.a + ap.b
        }
    }

    static void Main()
    {
        // Thread.CurrentThread.ManagedThreadId
        AddParams ap = new AddParams(10, 10);
        Thread t = new Thread(new ParameterizedThreadStart(Add));
        t.Start(ap);
        Thread.Sleep(5);
        Console.ReadLine();
    }
}

// 强制等待版本
class Program
{
    private static AutoResetEvent waitHandle = new AutoResetEvent(false);
    static void Main()
    {
        // Thread.CurrentThread.ManagedThreadId
        AddParams ap = new AddParams(10, 10);
        Thread t = new Thread(new ParameterizedThreadStart(Add));
        t.Start(ap);

        WaitHandle.WaitOne();
    }

    static void Add(object data)
    {
        if(data is AddParams)
        {
            // ap.a + ap.b
            waitHandle.Set();
        }
    }
}

// 并发问题
public class Printer
{
    public void PrintNumbers()
    {
        for(int _i = 0; _i < 10; _i++)
        {
            Random r = new Random();
            Thread.Sleep(1000 * r.Next(5));
            // _i
        }
    }

    static void Main()
    {
        Printer p = new Printer();
        Thread[] threads = new Thread[10];
        for(int _i = 0; _i < 10; _i++)
        {
            threads[_i] = new Thread(new ThreadStart(p.PrintNumbers));
            threads[_i].Name = string.Format("{0}", _i);
        }

        foreach(Thread t in threads)
        {
            t.Start();
        }
    }
}

// 线程同步 lock
// 试图锁定一个实例级对象私有方法时,用方法本身所在对象的引用即可。
private void SomePrivateMethod()
{
    lock(this)
    {
        //
    }
}

public class Printer
{
    private object threadLock = new object();
    public void PrintNumbers()
    {
        lock(threadLock)
        {
            for(int _i = 0; _i < 10; _i++)
            {
                Thread.Sleep(1000);
                Console.Write("{0}", i);
            }
        }
    }
}

// 线程同步 System.Threading.Monitor
public void PrintNumbers()
{
    Monitor.Enter(threadLock);
    try
    {
        // Thread.CurrentThread.Name
        for(int _i = 0; _i < 10; _i++)
        {
            Random r = new Random();
            Thread.Sleep(1000 * r.Next(5));
            Console.Write("{0}", _i);
        }
    }
    finally
    {
        Monitor.Exit(threadLock);
    }
}

// System.Threading.Interlocked
CompareExchange(ref x1, x2, x3)// if(x1 == x3) x1 = x2
Decrement
Exchange(ref x1, x2)// x1 = x2
Increment

public void AddOne()
{
    lock(myLockToken)
    {
        intVal++;
    }
}

// 改变后
public void AddOne()
{
    int newVal = Interlocked.Increment(ref intVal);
}

// 用[Synchronization]进行同步
// System.Runtime.Remoting.Contexts
// 被修饰类的对象放在同步上下文。使对象的所有实例成员线程安全。会全面降低性能。
// ContextBoundObject及其派生类不能在上下文边界中移动
using System.Runtime.Remoting.Context;
...

[Synchronization]
public class Printer : ContextBoundObject
{
    public void PrintNumbers()
    {
        //
    }
}

// TimerCallback
class Program
{
    static void PrintTime(object state)
    {
        // DateTime.Now.ToLongTimeString
    }

    static void Main()
    {
        TimerCallback timeCB = new TimerCallback(PrintTime);
        Timer t = new Timer(
        timeCB, "hello", 0, 1000);
        Console.WriteLine("Hit key to terminate");
    }
}

// 线程池
public static class ThreadPool
{
    ...
    public static bool QueueUserWorkItem(WaitCallback callBack);
    public static bool QueueUserWorkItem(WaitCallback callBack, object state);
}

class Program
{
    static void Main()
    {
        Printer p = new Printer();
        WaitCallback workItem = new WaitCallback(PrintTheNumbers);
        for(int _i = 0; _i < 10; _i++)
        {
            ThreadPool.QueueUserWorkItem(workItem, p);
        }
    }

    static void PrintTheNumbers(object state)
    {
        Printer task = (Printer)state;
        task.PrintNumbers();
    }
}

猜你喜欢

转载自blog.csdn.net/x13262608581/article/details/82286203