static async void Start() { string s = "ass"; Console.WriteLine(getMemory(s)+"Hello World!" + Thread.CurrentThread.ManagedThreadId); await AsyncMethod(); Console.WriteLine(getMemory(s) + "End World!" + Thread.CurrentThread.ManagedThreadId); Console.WriteLine(); } static async Task AsyncMethod() { await Task.Run(() => { Console.WriteLine("AsyncMethod 执行," + Thread.CurrentThread.ManagedThreadId); }); }
public static string getMemory(object o) // 获取引用类型的内存地址方法
{
GCHandle h = GCHandle.Alloc(o, GCHandleType.WeakTrackResurrection);
IntPtr addr = GCHandle.ToIntPtr(h);
return "0x" + addr.ToString("X");
}
红色的变量的 地址在await 两边一样吗?
是不一样的!
getMemory 这个方法换个写法就一样了:
public static string getMemory(object o) // 获取引用类型的内存地址方法 { GCHandle h = GCHandle.Alloc(o, GCHandleType.Pinned); IntPtr addr = h.AddrOfPinnedObject(); return "0x" + addr.ToString("X"); }
这个值应该是一个的。至少地址是一个。因为引用类型都是在堆上。堆是进程所有的。
async 和await 是成对出现的。有一个注意的点:async 是方法的修饰符,这个方法的await 之后的是回调。出了这个方法就不是的了。
在Winform 程序的Buttion_Click() 方法中,使用了这种异步语法,是没问题的,
private async void button1_Click(object sender, EventArgs e) { textBox1.Text += "zzz " + Thread.CurrentThread.ManagedThreadId.ToString() + " "; await Task.Run(() => { Thread.Sleep(2000); }); button1.Text += "2"; MessageBox.Show("))))))))))))))))s"); textBox1.Text += "ttt " + Thread.CurrentThread.ManagedThreadId.ToString()+" "; }
这个Buttion_Click 上可以写async! Await 后面的代码,是主线程操作了控件,这是编译器知道这个程序,然后进行了相应的处理。
async 这种语法,在Web项目中,会增加吞吐量,不会缩短对单个请求的响应时间。
下面是一个测试:
1 public static async void Test() 2 { 3 var t1= Task.Run(() => { 4 Thread.Sleep(2000); 5 Console.WriteLine("Sleep over"); 6 }); 7 8 t1.Wait(); 9 Console.WriteLine("Sleep over....1"); 10 11 var t2 = Task.Run(() => { 12 13 Thread.Sleep(2000); 14 Console.WriteLine("Sleep over 2"); 15 }); 16 17 t2.Wait(); 18 Console.WriteLine("Sleep over.....2"); 19 } 20 21 public static void Main(string[] args) 22 { 23 Console.WriteLine("start.."); 24 Test(); 25 Console.WriteLine("over"); 26 Console.ReadLine(); 27 }
start..
Sleep over
Sleep over....1
Sleep over 2
Sleep over.....2
over
Wait(); 换成 awiat t
打印如下:
start..
over
Sleep over
Sleep over....1
Sleep over 2
Sleep over.....2
下面是一个Async 的解析后的治理:
static async Task Main() { Console.WriteLine("111111111111111"); await Task.Run(() => { Console.WriteLine("2222222222222"); }); Console.WriteLine("33333"); }
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; public class button1_Click : IAsyncStateMachine { public int state1; public AsyncVoidMethodBuilder t__builder; public object sender; public EventArgs e; private TaskAwaiter taskWaiter; private void MoveNext() { int num = state1; try { TaskAwaiter awaiter; if (num != 0) { Console.WriteLine("111111111111111"); awaiter = Task.Run(delegate { Console.WriteLine("2222222222222"); }).GetAwaiter(); if (!awaiter.IsCompleted) { num = (state1 = 0); taskWaiter = awaiter; button1_Click stateMachine = this; t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); return; } } else { awaiter = taskWaiter; taskWaiter = default(TaskAwaiter); num = (state1 = -1); } awaiter.GetResult(); Console.WriteLine("33333"); } catch (Exception exception) { state1 = -2; t__builder.SetException(exception); return; } state1 = -2; t__builder.SetResult(); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } }