您可以通过在控制器中的同步代码上使用Task.Run来提高吞吐量吗?

时间:2021-10-31 02:20:04

In my controller I need to call a method BlockingHttpRequest() which makes an http request. It is relatively slow running, and blocks the thread.
I am not in a position to refactor that method to make it async.

在我的控制器中,我需要调用一个方法BlockingHttpRequest()来生成一个http请求。它运行相对较慢,并阻塞线程。我无法重构该方法以使其异步。

Is it better to wrap this method in a Task.Run to at least free up a UI/controller thread?
I'm not sure if this really improves anything, or just makes more work.

是否最好将此方法包装在Task.Run中以至少释放UI /控制器线程?我不确定这是否能真正改善任何事情,或者只是做得更多。

public class MyController : Controller
{
    public async Task<PartialViewResult> Sync()
    {
        BlockingHttpRequest();
        return PartialView();
    }

    public async Task<PartialViewResult> Async()
    {
        await Task.Run(() => BlockingHttpRequest());
        return PartialView();
    }
}

In practice I have a couple of situations like this, where BlockingHttpRequest() takes 500ms and 5000ms respectively.

在实践中我有几个这样的情况,其中BlockingHttpRequest()分别需要500ms和5000ms。


I understand that Task.Run() will not make my function return sooner.

我知道Task.Run()不会让我的函数更快返回。

I thought that there might be some benefit of increased throughput. By freeing up the controller's thread, does that make it available to other users? This would imply that in MVC there is a difference between controller threads and background worker threads.

我认为增加吞吐量可能会带来一些好处。通过释放控制器的线程,这是否使其可供其他用户使用?这意味着在MVC中,控制器线程和后台工作线程之间存在差异。

2 个解决方案

#1


3  

By freeing up the controller's thread, does that make it available to other users?

通过释放控制器的线程,这是否使其可供其他用户使用?

Yes, it does.

是的,它确实。

This would imply that in MVC there is a difference between controller threads and background worker threads.

这意味着在MVC中,控制器线程和后台工作线程之间存在差异。

No, there is not. Because just as you're freeing up a thread pool thread that can now go service other requests, you're also consuming a new thread pool thread that now cannot go service other requests. So the total number of threads able to go work on other requests is the same.

不,那里没有。因为就像你正在释放一个现在可以为其他请求提供服务的线程池线程一样,你也在使用一个新的线程池线程,现在它无法为其他请求提供服务。因此,能够处理其他请求的线程总数是相同的。

I thought that there might be some benefit of increased throughput.

我认为增加吞吐量可能会带来一些好处。

There is not. You're wasting some time context switching between threads, waiting for the new worker to be scheduled, and other overhead related to the work that you're doing, and you're getting nothing in return.

那没有。您在线程之间浪费了一些时间上下文切换,等待新工作程序的调度,以及与您正在进行的工作相关的其他开销,并且您得不到任何回报。

#2


0  

Because the method is blocking, moving it onto a different thread achieves nothing. Just wastes one thread instead of another, both of which were created equal.

因为该方法是阻塞的,所以将它移动到另一个线程上什么都不会实现。只是浪费一个线程而不是另一个线程,两者都是平等的。

Furthermore, because a thread is still wasted either way there is no increased scalability or throughput.

此外,由于线程仍然以任何方式浪费,因此没有增加的可伸缩性或吞吐量。

#1


3  

By freeing up the controller's thread, does that make it available to other users?

通过释放控制器的线程,这是否使其可供其他用户使用?

Yes, it does.

是的,它确实。

This would imply that in MVC there is a difference between controller threads and background worker threads.

这意味着在MVC中,控制器线程和后台工作线程之间存在差异。

No, there is not. Because just as you're freeing up a thread pool thread that can now go service other requests, you're also consuming a new thread pool thread that now cannot go service other requests. So the total number of threads able to go work on other requests is the same.

不,那里没有。因为就像你正在释放一个现在可以为其他请求提供服务的线程池线程一样,你也在使用一个新的线程池线程,现在它无法为其他请求提供服务。因此,能够处理其他请求的线程总数是相同的。

I thought that there might be some benefit of increased throughput.

我认为增加吞吐量可能会带来一些好处。

There is not. You're wasting some time context switching between threads, waiting for the new worker to be scheduled, and other overhead related to the work that you're doing, and you're getting nothing in return.

那没有。您在线程之间浪费了一些时间上下文切换,等待新工作程序的调度,以及与您正在进行的工作相关的其他开销,并且您得不到任何回报。

#2


0  

Because the method is blocking, moving it onto a different thread achieves nothing. Just wastes one thread instead of another, both of which were created equal.

因为该方法是阻塞的,所以将它移动到另一个线程上什么都不会实现。只是浪费一个线程而不是另一个线程,两者都是平等的。

Furthermore, because a thread is still wasted either way there is no increased scalability or throughput.

此外,由于线程仍然以任何方式浪费,因此没有增加的可伸缩性或吞吐量。