代码改变世界

async/await 的引用

2019-09-05 17:32  qgbo  阅读(807)  评论(0编辑  收藏  举报

1.async await 在桌面程序和 服務程序处理不一样:桌面程序 await  后面,默认是还给UI线程的。服务端程序是线程池随机选取的,大概率另外的线程,可以通过.ConfigureAwait(false) 来配置。

以下的桌面程序,会死锁。除非在14 行加上 .ConfigureAwait(false) ,(第9 行也不行)。可能是为了防止桌面程序用的问题,很多库全是这样设置ide。

 1  private async void button1_Click(object sender, EventArgs e)
 2         {
 3             DoSomethingAsync().Wait();
 5         }
 6 
 7         async Task DoSomethingAsync()
 8         {
 9             await DoSomething2Async();
10         }
11 
12         async Task DoSomething2Async()
13         {
14             await Task.Delay(TimeSpan.FromSeconds(2));
15             button1.Text = val.ToString();
16             Console.WriteLine(val);
17         }

 

2.红色的变量的 地址在await  两边一样吗?

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");
}

 

 

是不一样的!

 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() + "\r\n";
            await Task.Run(() => { Thread.Sleep(2000); });
            button1.Text += "2";
            MessageBox.Show("))))))))))))))))s");

            textBox1.Text += "ttt " + Thread.CurrentThread.ManagedThreadId.ToString()+"\r\n";

        }

  

这个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 的解析后的:

    Console.WriteLine("111111111111111");
            await Task.Run(() => {
                Console.WriteLine("2222222222222");
            });
            await Task.Run(() => {
                Console.WriteLine("3333333333333");
            });
            Console.WriteLine("444444");
internal class Program
{
    [CompilerGenerated]
    private sealed class <Main>d__0 : IAsyncStateMachine
    {
        public int <>1__state;

        public AsyncTaskMethodBuilder <>t__builder;

        public string[] args;

        private TaskAwaiter <>u__1;

        private void MoveNext()
        {
            int num = <>1__state;
            try
            {
                TaskAwaiter awaiter;
                TaskAwaiter awaiter2;
                if (num != 0)
                {
                    if (num == 1)
                    {
                        awaiter = <>u__1;
                        <>u__1 = default(TaskAwaiter);
                        num = (<>1__state = -1);
                        goto IL_0116;
                    }
                    Console.WriteLine("111111111111111");
                    awaiter2 = Task.Run(delegate
                    {
                        Console.WriteLine("2222222222222");
                    }).GetAwaiter();
                    if (!awaiter2.IsCompleted)
                    {
                        num = (<>1__state = 0);
                        <>u__1 = awaiter2;
                        <Main>d__0 stateMachine = this;
                        <>t__builder.AwaitUnsafeOnCompleted(ref awaiter2, ref stateMachine);
                        return;
                    }
                }
                else
                {
                    awaiter2 = <>u__1;
                    <>u__1 = default(TaskAwaiter);
                    num = (<>1__state = -1);
                }
                awaiter2.GetResult();
                awaiter = Task.Run(delegate
                {
                    Console.WriteLine("3333333333333");
                }).GetAwaiter();
                if (!awaiter.IsCompleted)
                {
                    num = (<>1__state = 1);
                    <>u__1 = awaiter;
                    <Main>d__0 stateMachine = this;
                    <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
                    return;
                }
                goto IL_0116;
                IL_0116:
                awaiter.GetResult();
                Console.WriteLine("444444");
            }
            catch (Exception exception)
            {
                <>1__state = -2;
                <>t__builder.SetException(exception);
                return;
            }
            <>1__state = -2;
            <>t__builder.SetResult();
        }

        void IAsyncStateMachine.MoveNext()
        {
            //ILSpy generated this explicit interface implementation from .override directive in MoveNext
            this.MoveNext();
        }

        [DebuggerHidden]
        private void SetStateMachine(IAsyncStateMachine stateMachine)
        {
        }

        void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
        {
            //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
            this.SetStateMachine(stateMachine);
        }
    }

    [AsyncStateMachine(typeof(<Main>d__0))]
    [DebuggerStepThrough]
    private static Task Main(string[] args)
    {
        <Main>d__0 stateMachine = new <Main>d__0();
        stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
        stateMachine.args = args;
        stateMachine.<>1__state = -1;
        stateMachine.<>t__builder.Start(ref stateMachine);
        return stateMachine.<>t__builder.Task;
    }

    [DebuggerStepThrough]
    private static void <Main>(string[] args)
    {
        Main(args).GetAwaiter().GetResult();
    }
}
View Code

 

如果把 33333 得这个await 删掉,最后结果:

internal class Program
{
    [CompilerGenerated]
    private sealed class <Main>d__0 : IAsyncStateMachine
    {
        public int <>1__state;

        public AsyncTaskMethodBuilder <>t__builder;

        public string[] args;

        private TaskAwaiter <>u__1;

        private void MoveNext()
        {
            int num = <>1__state;
            try
            {
                TaskAwaiter awaiter;
                if (num != 0)
                {
                    Console.WriteLine("111111111111111");
                    awaiter = Task.Run(delegate
                    {
                        Console.WriteLine("2222222222222");
                    }).GetAwaiter();
                    if (!awaiter.IsCompleted)
                    {
                        num = (<>1__state = 0);
                        <>u__1 = awaiter;
                        <Main>d__0 stateMachine = this;
                        <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
                        return;
                    }
                }
                else
                {
                    awaiter = <>u__1;
                    <>u__1 = default(TaskAwaiter);
                    num = (<>1__state = -1);
                }
                awaiter.GetResult();
                Console.WriteLine("444444");
            }
            catch (Exception exception)
            {
                <>1__state = -2;
                <>t__builder.SetException(exception);
                return;
            }
            <>1__state = -2;
            <>t__builder.SetResult();
        }

        void IAsyncStateMachine.MoveNext()
        {
            //ILSpy generated this explicit interface implementation from .override directive in MoveNext
            this.MoveNext();
        }

        [DebuggerHidden]
        private void SetStateMachine(IAsyncStateMachine stateMachine)
        {
        }

        void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
        {
            //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
            this.SetStateMachine(stateMachine);
        }
    }

    [AsyncStateMachine(typeof(<Main>d__0))]
    [DebuggerStepThrough]
    private static Task Main(string[] args)
    {
        <Main>d__0 stateMachine = new <Main>d__0();
        stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
        stateMachine.args = args;
        stateMachine.<>1__state = -1;
        stateMachine.<>t__builder.Start(ref stateMachine);
        return stateMachine.<>t__builder.Task;
    }

    [DebuggerStepThrough]
    private static void <Main>(string[] args)
    {
        Main(args).GetAwaiter().GetResult();
    }
}