提问者:小点点

是否可以在C#中创建自己的非阻塞异步任务


C#中的许多内置IO函数是非阻塞的,也就是说,它们在等待操作完成时不会抓住线程不放。

例如,返回任务system.io.file.ReadAllLinesAsync是非阻塞的。

它不只是暂停它正在使用的线程,它实际上释放了线程,以便其他进程可以使用它。

我假设这是通过调用OS来实现的,这样OS在检索到文件时就回调到程序,而程序不必浪费一个线程来等待它。

是否可以自己创建一个非阻塞的异步任务?

执行类似thread.sleep()的操作显然不会像system.io.file.ReadAllLinesAsync那样释放当前线程。

我意识到Hibernate线程并不占用CPU资源,但它仍然占用线程,这在处理大量请求的web服务器中可能是一个问题。

我说的不是一般情况下如何生成任务。我说的是用于处理文件/网络调用的内置C#函数在线程等待时如何释放线程。


共1个答案

匿名用户

System.Threading.Tasks命名空间中的Task类应该提供您要查找的功能。您可以使用它创建task对象来运行您试图实现的任何进程。例如,如果有一个方法int longrunner需要很长时间执行,并且希望异步访问它,则可以定义tasklongrunnerasync:

public Task<int> LongRunnerAsync() {
    return Task.Run( () => LongRunner() );
}

定义自定义任务有几种方法:

  • 使用task.run(...)方法定义任务。这是定义任务的默认方法,因为它编写起来很简单,并且可以立即启动任务。您可以通过调用以下命令来执行此操作:
Task.Run( () => {
    doWork();
}
  • 定义任务以使用构造函数运行预定义操作。这允许您定义一个不立即启动的任务。这可以通过以下方式完成:
Action action = () => doWork();
Task task = new Task(action);
task.Start();
  • 使用Task.Factory.StartNew(...)方法定义任务。此方法允许比task.run(...)更多的自定义,但提供了类似的功能。只有在有特定原因需要任务时,我才建议使用此方法。run(...)

请参阅Microsoft的文档页。