-1

I have a scenario where in My .Net Standard project,I have a api

public async Task SendMessageAsync(){

    await _service1.SendmessageToRestServiceAsync(); - calls a rest service

    await _service2.SendMessageToKafkaAsync(); - calls a kakfaclient
}

The SDK users are using this service concurrently like 100,1000 times and reporting performance issues.

var tasks  = Enumerable.Range(1, 100).Select(i =>SendMessageAsync());
await Task.WhenAll(tasks);

I want to run await _service1.SendMessage(); in a way so that if even there is an exception it shouldn't stop await _service2.SendMessage();

As this call is mandatory always and shouldn't be affetced. All the concurrent Requests made for await _service1.Sendmessage(); should be run on a background thread or a different thread so that the performance is not affected.

I did check the ThreadPool.QueueWorkItem which accepts a delegate but it is return type is void.

Is there a way to run all the calls to await _service1.Sendmessage(); in a background.The order of execution is not important.

The documentation in the link says " Creates a task that will complete when all of the supplied tasks have completed." the SendMessageAsync is already called inside a whenall. My question is there a way, the call to SendmessageToRestServiceAsync can be independent of other task @PeterDuniho –

Yashwanth Kata
  • 817
  • 8
  • 21
  • 4
    Why not just do `await Task.WhenAll(_service1.Sendmessage(), _servic2.Sendmessage());`? – juharr Aug 27 '20 at 16:24
  • @juharr I am running the main SendMessageAsync already using whenAll. My question is there a way to run these async calls in different threads – Yashwanth Kata Aug 27 '20 at 16:28
  • 1
    If they are I/O bound then there's not much point in doing that. – juharr Aug 27 '20 at 16:39
  • 1
    @YashwanthChowdaryKata juharr already answered that. Tasks aren't threads, they are promises. You haven't explained what those methods do, but they are one of three things - fake async method that just return a completed task, already executing tasks, in which case the question is moot, or asynchronous operations that are already awaiting for completion and threads aren't involved at all – Panagiotis Kanavos Aug 27 '20 at 16:50
  • `The SDK users are using this service concurrently like 100,1000 times and reporting performance issues.` tell them to stop this, or force them by using eg an `ActionBlock` with a specific DOP, eg 10, to ensure no more than 10 executions can happen concurrently. Using an ActionBlock will take care of any heavy synchronous code that may be running in the `SendMessage()` calls – Panagiotis Kanavos Aug 27 '20 at 16:53
  • If both calls are async calls to remote services, there's no reason *not* to use `Task.WhenAll()`. I suspect performance problems are caused on the remote services due to the large number of concurrent calls. That's why *throttling* is actually good for perfomance – Panagiotis Kanavos Aug 27 '20 at 16:54
  • 1
    As presented here, all you need is `await Task.WhenAll(...)`. See duplicates. The discussion of performance does not seem relevant to the question you're asking. How you wait for an asynchronous result has nothing to do with how that asynchronous result is produced. Changing how you wait won't have any effect on the performance. If you need help with performance, a) **do some research**, then if you still need help b) post a new question that includes a [mcve] that demonstrates your problem, explain what you've tried to fix it, and what _specifically_ you need help with. – Peter Duniho Aug 27 '20 at 16:58
  • the documentation in the link says "" Creates a task that will complete when all of the supplied tasks have completed." the SendMessageAsync is already called inside a whenall.My question is there a way the call to SendmessageToRestServiceAsync independent of other task @PeterDuniho – Yashwanth Kata Aug 27 '20 at 17:01
  • _"My question is there a way the call to SendmessageToRestServiceAsync independent of other task"_ -- all due respect, your _question_ is in the post above. That said, the call to each of the two services _are already independent_. All you need is to not `await` each one individually, but rather pass the result of both calls to `WhenAll()`. Just like the answers to the duplicates say. The fact that the `SendMessageAsync()` method is also called using `WhenAll()` is completely irrelevant. It has nothing whatsoever to do with the implementation of `SendMessageAsync()`. – Peter Duniho Aug 27 '20 at 17:05

1 Answers1

0

Why not use await Task.WhenAll? Set two seperate Tasks to run and await them both.

public async Task SendMessageAsync()
{
   await Task.WhenAll(_service1.Sendmessage(), _servic2.Sendmessage());
}

The call to WhenAll(IEnumerable) method does not block the calling thread.

(https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.whenall?view=netcore-3.1)

Ryan Wilson
  • 10,223
  • 2
  • 21
  • 40
  • the documentation in the link says "" Creates a task that will complete when all of the supplied tasks have completed." the SendMessageAsync is already called inside a whenall.My question is there a way the call to SendmessageToRestServiceAsync independent of other task – Yashwanth Kata Aug 27 '20 at 17:01