-3

I'm trying to create an Web Service that runs an asynchronous function with .Net Core Framework.

This function must be executed in its own thread and return a new value that will be sent to the proper caller. The service must be listening for other calls while my async function is running, and start a new thread for each call. Once the thread is finished, I want the response to be sent to the original caller. I have tried this way :

In my controller I have :

[Route("api/orchestration")]
public class OrchController : Controller
{
    [HttpGet("{value}")]
    public void RunOrchestration(int value)
    {
        Program.GetResultAsync(value); // Notice that no value is returned but it respects the asynchronicity and the multithreading as asked
    }
}

In my main class I have :

public async static Task<string> GetResultAsync(int i)
{
    return await OrchestrationAsync(i);
}

public static Task<string> OrchestrationAsync(int i)
{
    return Task.Run<string>(() => { return r = Orchestration(i); });
}

public static string Orchestration(Object i)
{
    // This function is an orchestrator of microservices that talk asynchronously through a MOM 
    // Just consider that it returns the value I want in a string
    return result;
}

As you can see I want my function GetResultAsync to return a string with the value that will be sent to the caller. Yet I can't have something like this (see code below) because GetResultAsync returns a Task and not a string :

public string RunOrchestration(int value)
{
    return r = Program.GetResultAsync(value);
}

And if I put an await in RunOrchestration, it will wait for the response and will behave as a synchronous function.

Anyone has an idea on how to get my response and give it back to the proper caller ?

Thank's in advance ! :)

vimotte
  • 1
  • 1
  • 1
  • Read up on SignalR – Nkosi Aug 03 '17 at 16:52
  • 1
    async != parallel execution – Tseng Aug 03 '17 at 16:53
  • 1
    `The service must be listening for other calls while my async function is running, and start a new thread for each call` -> You do know that calls are handled concurrent by default unless you have disabled that on purpose? So why this construction? – Peter Bons Aug 03 '17 at 17:58
  • Controller actions run in their own threads; the service handles any number of requests at once; and they all return to their original callers. This is all built-in. What behavior are you asking for? – Stephen Cleary Aug 04 '17 at 01:00
  • If I call directly Orchestration(value) in my controller, the web app will wait until the response is returned before handling any other request. I want it to be still listening and start a new thread in parallel for each call. – vimotte Aug 04 '17 at 08:15

2 Answers2

6

I wish I could just somehow broadcast at once to every .NET developer in the world: async is not multithreading/parallel processing/background processing, etc.

Async does one and only one thing: it allows the current thread to be returned to the pool if it's idle. That's it. Period. End of story. If you're doing something like creating a new thread, that effectively idles the original thread allowing it to be returned to the pool, but you still have a thread. In other words, you did absolutely nothing but add a bunch of overhead and context switching to your code, making it less efficient, not more.

What you need here is a true background process. You can use something like Hangfire to fire off a task, and then that task can be handled by something. That could be a console app, another web application, an Azure Function, whatever. The point is that it's external to your main web application. Then, you can immediately return, without waiting for that thing, whatever it is, to finish. You can, also, utilize something like SignalR and web workers to push status updates to the client.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
0

Of course, the return value of GetResultAsync is Task (not a string) This is exactly what it should be. You probably misunderstood the concept of await/async. if you want string - you should call

await Program.GetResultAsync(value)

Read this topic :

How and When to use `async` and `await`

Nevertheless, such construction is futile. You are not gaining anything by async/await here.

Piotr
  • 1,155
  • 12
  • 29