1.委托的BeginEnvoke/EndInvoke
BeginEnvoke\EndInvoke是委托的异步版本。
public class AsyncFroDelegate { public delegate int AddHandler(int a, int b); public static int Add(int a, int b) { Console.WriteLine($"线程 {Thread.CurrentThread.ManagedThreadId} in add()"); Thread.Sleep(3000); Console.WriteLine("计算完成!"); return a + b; } public static void AsyncInvoke1() { Console.WriteLine("===异步调用 AsyncInvokeTest==="); AddHandler handler = new AddHandler(Add); IAsyncResult result = handler.BeginInvoke(1, 2, null, null); //EndInvoke,使得主线程处于阻塞状态 Console.WriteLine($"线程 {Thread.CurrentThread.ManagedThreadId} in AsyncInvoke1()"); Console.WriteLine("打印EndInvoke的结果 =" + handler.EndInvoke(result)); Console.WriteLine("继续做别的事情。。。"); Console.ReadKey(); } }
BeginInvoke使得CLR创建了一个新的线程去执行Add方法。此时主线程不受影响可以继续做其他事情。直到遇到EndInvoke,需要等待异步调用结果才被阻塞。如果主线程不依赖这个调用结果。可是使用回调,让主线不被阻塞。
/// <summary>
/// 异步回调
/// </summary>
public static void AsyncInoke3()
{
Console.WriteLine($"线程 {Thread.CurrentThread.ManagedThreadId} in AsyncInoke3()");
AddHandler handler = new AddHandler(Add);
IAsyncResult arr = handler.BeginInvoke(1, 2, myCallback, handler);
Console.WriteLine("主线程完成");
}
private static void myCallback(IAsyncResult ar)
{
Console.WriteLine($"线程 {Thread.CurrentThread.ManagedThreadId} in myCallback()");
//AddHandler handler = (AddHandler)((AsyncResult)ar).AsyncDelegate;
//AsyncState就是通过BeginInvoke函数的最后一个参数传递过来的的
AddHandler handler1 = (AddHandler)ar.AsyncState;
//Console.WriteLine("调用结果" + handler.EndInvoke(ar));
Console.WriteLine("调用结果" + handler1.EndInvoke(ar));
}
2.Thread
public Thread(ThreadStart start);
public Thread(ParameterizedThreadStart start);
public Thread(ThreadStart start, int maxStackSize);
public Thread(ParameterizedThreadStart start, int maxStackSize);
ParameterizedThreadStart 带一个参数,无返回值的委托
maxStackSize 线程要使用的堆栈的大小,默认1M。
public class AsyncForThread { public static void Client() { Thread thread1 = new Thread(Print); thread1.Start(); Thread thread2 = new Thread(PrintEx); thread2.Start("test"); } private static void PrintEx(object content) { int threadID = Thread.CurrentThread.ManagedThreadId; Console.WriteLine($"当前线程ID:{threadID}\t{content}"); } private static void Print() { int threadID = Thread.CurrentThread.ManagedThreadId; Console.WriteLine($"当前线程ID:{threadID} 无参数"); } }
3.ThreadPool