c#async await threading-它是如何工作的?

时间:2017-03-21 11:38:39

标签: c# multithreading asynchronous threadpool

async / CopyToAsync / WriteAsync应该ReadAsync有一些功能。

我可以对它们await进行操作,我的线程继续处理其他代码,当这些功能结束时,它们会通知我。 它们不会浪费CPU时间,我也不需要为它们打开另一个线程。

但是,当我想做一些我没有这个功能的async工作时,比如删除文件。

我可以像这样包装这个函数:

public static class FileExtensions {
   public static Task DeleteAsync(this FileInfo fi) {
      return Task.Factory.StartNew(() => fi.Delete() );
   }
}

并调用此函数,如:

FileInfo fi = new FileInfo(fileName);
await fi.DeleteAsync();

我想知道的是:

1 - 当我做这个包装器时会发生什么? 这将为此打开新线程(来自ThreadPool)在等待此功能时浪费CPU时间? 真正的async函数和这个包装器有什么不同?

2 - 我怎么知道我在C#上使用的函数在内核之前是否真的是async函数?

谢谢!

1 个答案:

答案 0 :(得分:3)

首先,您的包装器应该使用Task.Run而不是StartNewStartNew is a dangerous, low-level API,你不应该使用它。

  

当我做这个包装器时会发生什么?

它将在线程池线程上运行delete-file操作。

  

这将为此(从ThreadPool)打开新线程,在等待此功能时浪费CPU时间?

没有; CPU不用于等待此I / O操作。线程池线程处于阻塞状态并从CPU中交换出来。

我称之为"假异步"因为它是出现异步的方法,但实际上只是阻塞线程池线程。

  

真正的异步函数和这个包装器有什么不同?

我在博客上详细解释了这一点,但其核心是pure async operations do not require a thread to be blocked

  

我怎么知道我在C#上使用的函数在内核之前是否真的是异步函数?

你不能;你需要知道它的实现。

在某些情况下,您可以推断出它是否真的是异步。例如,Win32子系统不允许异步文件打开或删除,因此您可以推断出任何"异步"文件打开或删除操作不是真正的异步。