0

I have a switch case condition with async Task methods inside async Task method Message.

async static Task Message()
{
    switch (message.Text)
    {
        case "1":
            task1().Wait();
            break;
        case "2":
            task2().Wait();
            break;
        case "3":                               
            task3().Wait();
            break;

        default:
            break;
    }
}    

and task1 for example itself. When it's completed, the cycle goes back to the Message method. task2 and task3 are similar to task1 just with different text info.

async static Task task1()
{
    try
    {               
        while (true)
        {
            //some code
            Message().Wait();
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("Error" + ex);
    }
}

The problem is when some user is inside task1(or task2, task3), other user can't get response from the Message method until task1 is finished. The question is how to execute the tasks in switch case in parallel. My main method

static void Main(string[] args)
{
    try
    {
        Parallel.Invoke(
        () => CreateHostBuilder(args).Build().Run(),
        () => Message().Wait());
    }
    catch (Exception ex)
    {
        Console.WriteLine("Error" + ex);
    }
}

here is CreateHostBuilder

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureServices((hostContext, services) =>
        {
            //
        });
Peter Csala
  • 17,736
  • 16
  • 35
  • 75
coxcoxgo
  • 39
  • 1
  • 5
  • Why use a switch/case with a wait, instead of a continuation? – Christopher Aug 16 '21 at 11:28
  • @Christopher what u mean? – coxcoxgo Aug 16 '21 at 11:33
  • 1
    Was the problem resolved? – Md Farid Uddin Kiron Aug 17 '21 at 02:48
  • @MdFaridUddinKiron no, the problem is in inner Task task1(or task2,3). It accepts only one user until this task is finished. Don't know how to solve this issue. May be problem is in GetUpdatesAsync method which also exist in Message method, or using of concurrent dictionary(from here https://stackoverflow.com/questions/51933004/save-user-messages-sent-to-bot-and-send-finished-form-to-other-user) limits number of users. Can u help please. – coxcoxgo Aug 18 '21 at 12:51
  • You could try either of them `AUTO RESET EVENT`, `MUTEX`, `SEMAPHORE` to manage parallel process. You can have a look on [official docs here](https://learn.microsoft.com/en-us/dotnet/standard/threading/overview-of-synchronization-primitives#waithandle-class-and-lightweight-synchronization-types) – Md Farid Uddin Kiron Aug 19 '21 at 01:06
  • @MdFaridUddinKiron ty for response. I tried a lot of different ways, but stucked with this issue. Posted a new question with detailed explanation(https://stackoverflow.com/questions/68859452/how-to-get-parallel-access-to-the-method-for-multiple-users). I will be grateful, if u will help to solve this problem. – coxcoxgo Aug 20 '21 at 09:23
  • Thanks for the update , I will try to have a look on your link. Let me know if you have any further concern. – Md Farid Uddin Kiron Aug 23 '21 at 01:20

1 Answers1

1

Use the await keyword instead of .Wait(). Wait() blocks the current thread, however await is non-blocking and works with a continuation callback. Moreover, the compiler should issue a warning when you do not use await in an async method

async static Task Message()
{
    switch (message.Text)
    {
        case "1":
            await task1();
            break;
        case "2":
            await task2();
            break;
        case "3":
            await task3();
            break;

        default:
            break;
    }
}
async static Task task1()
{
    try
    {
        while (true)
        {
            //some code
            await Message();

        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("Error" + ex);
    }

}

In your main method:

static async Task Main(string[] args)
{
    try
    {
 
        Task t1 = CreateHostBuilder(args).Build().RunAsync();
        Task t2 = Message();
    
        await Task.WhenAll(t1, t2);
    }
    ...
}
Amal K
  • 4,359
  • 2
  • 22
  • 44
  • 2
    Exception Handling is a pet peeve of mine. Catching Exception is a terrible idea, unless it is for logging and you let it go on afterwards. I consider code like that a deadly sin of exception handling. There are two articles on exception handling that explain why much better then I could: https://blogs.msdn.microsoft.com/ericlippert/2008/09/10/vexing-exceptions/ | https://www.codeproject.com/Articles/9538/Exception-Handling-Best-Practices-in-NET – Christopher Aug 16 '21 at 11:37
  • edited code , but it didn't work cause of main method. I can't use await for CreateHostBuilder, that's why await can't be added to Message in main. Any suggestion? Added main method in description – coxcoxgo Aug 16 '21 at 11:48
  • Can you include your `CreateHostBuilder` method in your post? `await` can only be used for async methods. – Amal K Aug 16 '21 at 11:50
  • added. CreateHostBuilder and Message must work in parallel – coxcoxgo Aug 16 '21 at 11:52
  • @coxcoxgo Please check the updated answer – Amal K Aug 16 '21 at 12:00
  • @coxcoxgo Did you use `RunAsync()`? – Amal K Aug 16 '21 at 12:06
  • where and how to use RunAsync()? added your code for Main, no errors. But still user2 can't get response from Message until user1 finish Task1. – coxcoxgo Aug 16 '21 at 12:28
  • @coxcoxgo I had edited the code in `Main` once more, did you add the updated code? – Amal K Aug 16 '21 at 12:38
  • yes, updated it. But still user2 can't get response from Message until user1 finish Task1. – coxcoxgo Aug 16 '21 at 12:49
  • @AmalK ty for your response. Can u look please at https://stackoverflow.com/questions/68859452/how-to-get-parallel-access-to-the-method-for-multiple-users It's related question in deep – coxcoxgo Aug 20 '21 at 11:15