创建新任务会生成后台线程还是线程池线程?

3

我正在尝试为ASP.NET应用程序异步调用数据库。如果我理解正确,我不希望使用线程池线程进行异步I/O调用,以便保持线程池处理请求。下面的代码会消耗我的线程池线程吗,还是生成一个后台线程?

    public IEnumerable<dynamic> DbCall(string sql)
    {
        return // DB Operation;
    }

    public Task<IEnumerable<dynamic>> DbCallAsync(string sql)
    {
        var task = new Task<IEnumerable<dynamic>>(() => this.DbCall(sql));
        task.Start();
        return task;
    }
2个回答

5

是的,使用Task构造函数会在另一个线程中执行代码,例如线程池线程。

你应该使用本质上异步的DB操作,而不是同步的。你不应该使用Task构造函数来构造代表异步操作的Task。你如何实现这一点将取决于你使用的API来执行IO。


我正在使用不支持异步的simple.data,并尝试弄清如何以异步方式调用它。问题在于我需要并行运行5个SQL语句,而不想阻塞6个线程池线程来完成此操作。 - Dale Alleshouse
2
@DaleAlleshouse 然后开始使用具有异步支持的查询机制,使您能够执行查询而不会阻塞线程。如果不这样做,您就别无选择了。 - Servy

2

默认调度程序上的任务在线程池上运行。它们不会默认启动新线程。这回答了你的问题。

话虽如此,您误解了异步IO的目的和内部工作原理。异步IO在运行时根本不消耗任何线程。但是,您并没有使用异步IO。您正在将IO移动到线程池中。这在ASP.NET中从来没有帮助过,它总是降低性能。

将阻塞工作移动到不同的线程如何可能有所帮助?您仍然会阻塞一个线程。只是不同的线程而已。如果您的线程池用尽,请增加限制。无需手动启动线程。

研究异步IO何时有益以及为什么有益。如果没有这种理解,您将无法成功使用它。


我稍微澄清一下... 无论如何,这是XY问题。 - usr
好吧,我想我就是不明白了。我原以为它会将处理I/O操作的当前线程释放回线程池,直到I/O操作完成。 - Dale Alleshouse
1
@DaleAlleshouse 是的。但是IO操作现在在不同的线程上同步运行。你这样做并没有获得任何优势。 - usr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接