如何避免异步方法使用新线程?

我读过 await/async 不应该创建/使用新线程,但编译器在幕后创建了一个 astate 机器......所以我尝试了这个,并且每次调用 F1 都使用来自 ThreadPool 的线程。


class Program

{

    static System.Threading.SemaphoreSlim sem =

        new System.Threading.SemaphoreSlim(20, 20);

    static async void F1()

    {

        await sem.WaitAsync();

        await sem.WaitAsync();

        await Task.Delay(6000);

        var threadId = GetCurrentThreadId();

        sem.Release();

        sem.Release();

    }


    static void Main(string[] args)

    {

        var threadId = GetCurrentThreadId();


        F1();

        F1();

        F1();

        F1();

        F1();

        F1();

        F1();

        F1();

        Task.Delay(30000).Wait();

    }

    [DllImport("kernel32.dll")]

    static extern uint GetCurrentThreadId();


}


哈士奇WWW
浏览 129回答 2
2回答

斯蒂芬大帝

您已经使用了await Task.Delay(6000),它保证不会同步完成,因此:完成将通过它可以返回的任何方式返回 - 通常是线程池(因为这里没有同步上下文在起作用)。线程池线程很便宜,只要你不长时间捆绑它们;如果它所做的只是捕获当前线程 id 并释放,它们应该在它们触发后几乎立即完成。代码需要在某处运行;你希望它在什么线程上运行?您的主线程当前处于阻塞Wait()调用中,因此它无法执行任何操作。注意:您几乎不应该调用.Wait()不完整的Task.
打开App,查看更多内容
随时随地看视频慕课网APP