Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait multiple threads for one result

I have a web service, where data for an identifier can be gotten (e.g. billing information for a customer id). In my client there are multiple threads. These threads call the method at the web service to get the data for the identifier.

Now it happens, that during a request to the web service for e.g CustomerID = 12345 another thread tries to call the web service for the same customer. Now I want to spare the server und to recycle the result of the request. Therefore I want to wait the second thread until the result of the first request is gotten and return the result also to the second thread.

An important requirement is, that if the second thread wants to get the data after the web request returned, a new request has to be sent. To illustrate my problem, I show a sequence diagram:

Can anybody explain me, how I can achieve this in C#.

like image 826
scher Avatar asked Oct 29 '25 16:10

scher


1 Answers

You can do something like this:

private static ConcurrentDictionary<string, Task<string>> s_urlToContents;

public static Task<string> GetContentsAsync(string url)
{
    Task<string> contents;
    if(!s_urlToContents.TryGetValue(url, out contents))
    {
        contents = GetContentsAsync(url);
        contents.ContinueWith(t => s_urlToContents.TryAdd(url, t); },
        TaskContinuationOptions.OnlyOnRanToCompletion |
        TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
    }
    return contents;
}

private static async Task<string> GetContentsAsync(string url)
{
    var response = await new HttpClient().GetAsync(url);
    return response.EnsureSuccessStatusCode().Content.ReadAsString();
}

This code caches an http request, if another thread wants access to the same request, you just return the already cached task, if it doesn't exist, you spawn the task and cache it for future requests.

like image 153
Nikola.Lukovic Avatar answered Oct 31 '25 06:10

Nikola.Lukovic



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!