对于许多并发的 http 请求,是否有一个好的线程模型?

发布于 2024-12-08 14:07:38 字数 391 浏览 1 评论 0原文

我的 .Net 和 Java 应用程序需要向 Web 服务同时发出许多请求,这需要很长的时间才能回复。因此,任何时候都可能有数千个未完成的 HTTP 请求。为了实现这一点,我可以让单个线程生成许多异步 HTTP 请求并处理响应,但我想了解任何允许发出同步 HTTP 请求而不需要使用数千个线程(因为相关的资源成本)的替代方案。任何解决方案都必须避免线程因等待 HTTP 响应而被阻塞。

我的问题有两个部分:

1)线程池可以用来做到这一点吗?我知道我可以将我的作业放入线程池队列中,并且线程池将在能够处理它们时处理它们,但是线程池工作线程可以避免被阻塞等待 http 响应吗?他们可以在等待期间去处理其他工作吗?

2)是否有其他方法可以实现这一点,同时保留 HTTP 同步 API 调用的简单性。

问候

My .Net and Java application needs to make many simultaneous requests to a web service which takes a notable length of time to reply. Consequently there may be thousands of outstanding HTTP requests at any one time. To implement this I could have a single thread generate many asynchronous HTTP requests and handle the responses but I want to understand any alternatives which allow synchronous HTTP requests to be made without requiring thousands of threads to be used because of the associated resource cost. Any solution must avoid threads being blocked waiting for HTTP responses.

My question has two parts:

1) Can Threadpools be used to do this? I know I can queue my jobs in the threadpool queue and the threadpool will process them as and when it is able to but can the threadpool worker threads avoid being blocked waiting for the http response? Can they go and process other jobs while they wait?

2) Is there some other way I can achieve this while retaining the simplicity of the HTTP synchronous API call.

Regards

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

杀手六號 2024-12-15 14:07:38

可以使用线程池来做到这一点吗?

就他们自己而言,不。

是否有其他方法可以实现此目的,同时保留 HTTP 同步 API 调用的简单性。

您是在谈论客户端 HTTP 调用 API 吗?如果是这样,有一种方法可以做到这一点,即使用异步服务器端实现。

Can Threadpools be used to do this?

By themselves, no.

Is there some other way I can achieve this while retaining the simplicity of the HTTP synchronous API call.

Are you talking about the client side HTTP call API? If so, there is a way to do this, by using an asynchronous server-side implementation.

歌入人心 2024-12-15 14:07:38

任务不会产生额外的线程,因此您可以节省性能损失,并且它们不会阻塞调用线程,因此我相信这将满足这两个需求。

string[] urls = GetUrls();
var requests = new Dictionary<string, Task<string>>()
var responses = new Dictionary<string, string>();

// send off each request and store the on-going task in a dictionary
foreach (string url in urls)
    requests.Add(url, Task.Factory.StarNew(() => return WebClient.DownloadString(url))

// get the results asynchronously
Task.Factory.StartNew(() => {
    foreach (var request in requests)
        responses.Add(request.key, request.Result)
 }

现在,当您收到回复时,您可以通过多种方式进行操作。上面就会一一得到每个任务的结果。当您调用 result 时,它将等待任务完成,从而阻塞调用方法,并且如果任务发生故障,则会在此时抛出异常。您还可以使用 Task.WaitAll(); 一次等待整个批次。由于调用 .Result 会阻塞调用方法,因此您还必须从任务内部检索结果。

该示例假设您发送 HTTP-GET 并希望结果为字符串,但无论您想要哪种 HTTP 方法或结果,您进行调用和获取结果的方式都是相同的。您还需要添加异常处理来捕获可能引发的任何异常。您可以在此处准备有关任务异常处理的信息。

Tasks do not spawn extra threads, so you save that performance hit, and they do not block the calling thread so I believe this will meet both those needs.

string[] urls = GetUrls();
var requests = new Dictionary<string, Task<string>>()
var responses = new Dictionary<string, string>();

// send off each request and store the on-going task in a dictionary
foreach (string url in urls)
    requests.Add(url, Task.Factory.StarNew(() => return WebClient.DownloadString(url))

// get the results asynchronously
Task.Factory.StartNew(() => {
    foreach (var request in requests)
        responses.Add(request.key, request.Result)
 }

Now when you get the response you can do it a couple of ways. The above will get the result of each task one by one. When you call result it will wait for the task to finish, blocking the calling method and will throw exceptions at this point if the task faults. You can also wait the entire batch at once with Task.WaitAll(); Since calling .Result blocks the calling method you will have to retrieve the results from inside a task as well.

The example assumes your sending HTTP-GETs and want the result as a string, but regardless of the HTTP method or result you want, the way you make the call and get the result will be the same. You also want to add exception handling to catch any exceptions that may be thrown. You can ready about task exception handling here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文