Home C# executing function after async function is finished executing
Reply: 3

C# executing function after async function is finished executing

user1640256
1#
user1640256 Published in 2018-01-11 11:30:08Z

I have to execute a batch process. The Ids are generated and stored in a list. I need to execute the function only after all the Ids are generated. The issue is these Ids are generated inside async function. And because I am using a third party API, marking this function async is mandatory. Here is the code:

static void SaveFiles()
{
    try
    {
            foreach (FileInfo file in files)
            {
                //The following is async function.
                MakeAnalysisRequest(file.FullName, file.Name);
            }

            //The following needs to be called only after the MakeAnalysisRequest function has populated "Ids"
            if (Ids.Count > 1)
                CallBatchProcess(Ids);

            Console.WriteLine("Processing images...");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("There was an error! ");
    }
    Console.ReadLine();
}

static async void MakeAnalysisRequest(string imageFilePath, string fileName)
{
    //Here a list is populated.
    //List<string> Ids = new List<string();
    Ids.Add(obj.Id);
}
Ivan Mladenov
2#
Ivan Mladenov Reply to 2018-01-11 11:42:20Z

Without an await in your async MakeAnalysisRequest it will be executed synchronously. If this is the case, all calls will end and your method will be executed after all.

But if MakeAnalysisRequest has an await statement, making it asynchronous, you could create a Task array and wait them all.

First change your method to return a Task

static async Task MakeAnalysisRequest(string imageFilePath, string fileName)
{
    //Here a list is populated.
    // Some await statement
    //List<string> Ids = new List<string();
    Ids.Add(obj.Id);
}

static void SaveFiles()
{
    try
    {
            var tasks = new List<Task>();

            foreach (FileInfo file in files)
            {
                //The following is async function.
                tasks.Add(MakeAnalysisRequest(file.FullName, file.Name));
            }

            Task.WaitAll(tasks.ToArray());

            //The following needs to be called only after the MakeAnalysisRequest function has populated "Ids"
            if (Ids.Count > 1)
                CallBatchProcess(Ids);

            Console.WriteLine("Processing images...");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("There was an error! ");
    }
    Console.ReadLine();
}
Alan Corrêa da Silva
3#
Alan Corrêa da Silva Reply to 2018-01-11 12:42:56Z

For what I understand you don't need to execute the method asynchronously. You just need to make a call to a asynchronous method. If that's the case you could simply use Wait() on the asynchronous call for your MakeAnalysisRequest method or even better, for the api method that you're calling.



    static void SaveFiles()
    {
        try
        {
            foreach (FileInfo file in files)
            {
                //The following is async function.
                MakeAnalysisRequest(file.FullName, file.Name).Wait(); // The only change
            }

            //The following needs to be called only after the MakeAnalysisRequest function has populated "Ids"
            if (Ids.Count > 1)
                CallBatchProcess(Ids);

            Console.WriteLine("Processing images...");
        }
        catch (Exception ex)
        {
            Console.WriteLine("There was an error! ");
        }
        Console.ReadLine();
    }

    static void async MakeAnalysisRequest(string imageFilePath, string fileName)
    {
        //Here a list is populated.
        //List Ids = new List();
        Ids.Add(obj.Id);
    }

It's important to note that this is going to make the call synchronous (it will wait until the asynchronous call is finished). If you intend to execute it asynchronously for real you'd need to change the way your application is implemented to keep it executing until an action to finish it is performed.

Shiv Prasad
4#
Shiv Prasad Reply to 2018-01-11 13:38:31Z

Make it MakeAnalysisRequest as Task. And call you that with multiple threads like

tasks.Add(Task.Factory.StartNew(() => MakeAnalysisRequest(fullName, name)));

And Wait for all thread completion and you can process with other code.

Code Sample:

static void SaveFiles(){
    List<Tasks> tasks = new List<Task>();
        try
        {
                foreach (FileInfo file in files)
                {
                    //The following is async function.
                    string fullName=file.FullName;
                    string name=file.Name;
                    tasks.Add(Task.Factory.StartNew(() => MakeAnalysisRequest(fullName, name)));
                }
                Task.WaitAll(tasks.ToArray());
                //The following needs to be called only after the MakeAnalysisRequest function has populated "Ids"
                if (Ids.Count > 1)
                    CallBatchProcess(Ids);

                Console.WriteLine("Processing images...");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("There was an error! ");
        }
        Console.ReadLine();
    }

    static async Task MakeAnalysisRequest(string imageFilePath, string fileName)
    {
        //Here a list is populated.
        //List<string> Ids = new List<string();
        Ids.Add(obj.Id);
    }
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.319032 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO