zoukankan      html  css  js  c++  java
  • C# Main函数中调用异步方法的2种实现

    As you discovered, in VS11 the compiler will disallow an async Main method. This was allowed (but never recommended) in VS2010 with the Async CTP.

    I have recent blog posts about async/await and asynchronous console programs in particular. Here's some background info from the intro post:

    If "await" sees that the awaitable has not completed, then it acts asynchronously. It tells the awaitable to run the remainder of the method when it completes, and then returns from the async method. Await will also capture the current context when it passes the remainder of the method to the awaitable.

    Later on, when the awaitable completes, it will execute the remainder of the async method (within the captured context).

    Here's why this is a problem in Console programs with an async Main:

    Remember from our intro post that an async method will return to its caller before it is complete. This works perfectly in UI applications (the method just returns to the UI event loop) and ASP.NET applications (the method returns off the thread but keeps the request alive). It doesn't work out so well for Console programs: Main returns to the OS - so your program exits.

    One solution is to provide your own context - a "main loop" for your console program that is async-compatible.

    If you have a machine with the Async CTP, you can use GeneralThreadAffineContext from My DocumentsMicrosoft Visual Studio Async CTPSamples(C# Testing) Unit TestingAsyncTestUtilities. Alternatively, you can use AsyncContext from my Nito.AsyncEx NuGet package.

    Here's an example using AsyncContextGeneralThreadAffineContext has almost identical usage:

    using Nito.AsyncEx;
    class Program
    {
        static void Main(string[] args)
        {
            AsyncContext.Run(() => MainAsync(args));
        }
    
        static async void MainAsync(string[] args)
        {
            Bootstrapper bs = new Bootstrapper();
            var list = await bs.GetList();
        }
    }

    Alternatively, you can just block the main Console thread until your asynchronous work has completed:

    class Program
    {
        static void Main(string[] args)
        {
            MainAsync(args).GetAwaiter().GetResult();
        }
    
        static async Task MainAsync(string[] args)
        {
            Bootstrapper bs = new Bootstrapper();
            var list = await bs.GetList();
        }
    }

    Note the use of GetAwaiter().GetResult(); this avoids the AggregateException wrapping that happens if you use Wait() or Result.

    Update, 2017-11-30: As of Visual Studio 2017 Update 3 (15.3), the language now supports an async Main - as long as it returns Task or Task<T>. So you can now do this:

    class Program
    {
        static async Task Main(string[] args)
        {
            Bootstrapper bs = new Bootstrapper();
            var list = await bs.GetList();
        }
    }

    The semantics appear to be the same as the GetAwaiter().GetResult() style of blocking the main thread. However, there's no language spec for C# 7.1 yet, so this is only an assumption.

    https://stackoverflow.com/questions/9208921/cant-specify-the-async-modifier-on-the-main-method-of-a-console-app

  • 相关阅读:
    悄悄蒙上你的眼睛 后门程序知识完全解析 java程序员
    教你认识网页中五种隐形的危险病毒 java程序员
    安全知识 黑客是如何攻击电子邮件的 java程序员
    著名黑客工具CC攻击的思路及防范方法 java程序员
    Educational Codeforces Round 45 (Rated for Div. 2) G GCD Counting
    Dual Palindromes
    2012暑假集训内部测试赛1
    hdu4380Farmer Greedy(多校3)
    sdutCity Horizon(离散化)
    USACO1.22Transformations
  • 原文地址:https://www.cnblogs.com/qixue/p/10515311.html
Copyright © 2011-2022 走看看