【问题标题】:Will creating a new task generate a background thread or a thread pool thread创建新任务会生成后台线程还是线程池线程
【发布时间】:2014-09-02 04:26:30
【问题描述】:

我正在尝试为 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;
    }

【问题讨论】:

    标签: c# asp.net multithreading async-await


    【解决方案1】:

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

    您应该使用本质上是异步而不是同步的 DB 操作。您根本不应该使用 Task 构造函数来构造代表异步操作的 Task。您如何执行此操作将取决于您用于执行 IO 的 API。

    【讨论】:

    • 我使用的是 simple.data,它不支持异步。我试图弄清楚如何将其称为异步。问题是我需要并行运行 5 条 sql 语句。我不想被阻塞 6 个线程池线程来完成这个。
    • @DaleAlleshouse 然后开始使用确实 具有异步支持并且允许您在不阻塞线程的情况下执行查询的查询机制。如果你不这样做,你在这件事上别无选择。
    【解决方案2】:

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

    也就是说,您误解了异步 IO 的目的和内部工作原理。异步 IO 在运行时根本不消耗任何线程。但是,您没有使用异步 IO。您正在将 IO 移动到线程池。这对 ASP.NET 没有帮助。它总是会降低性能。

    将阻塞工作转移到不同的线程有什么帮助?!您仍在阻塞线程。只是一个不同的。如果您的线程池已用尽,只需增加限制。无需手动启动线程。

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

    【讨论】:

    • 我澄清了一点……这就是 XY 问题。
    • 好吧,我想我当时不明白。我的印象是它会将处理 I/O 操作的当前线程释放回线程池,直到 I/O 操作完成。
    • @DaleAlleshouse 确实如此。但是 IO 操作现在在不同的线程上同步运行。这样做你什么也没赢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    • 2013-01-18
    • 1970-01-01
    相关资源
    最近更新 更多