1

I am trying to create an application for learning purposes going along with an Async in C# book. However I am having trouble implementing the ideas in the form of which i want. Please let me know if this is doable or not.

Basically, I have a console application with 3 classes. The user inputs some data on the console and then I have a class which executes a SQL command/query and creates a datatable. However the queries actually take quite a bit of time depending on the time of day so this is what I Want: I want to run the class/function which executes my sql query, executes some code right below it in the main program, and then wait for the sql query/data table to finish. After this I then do an export to excel. A portion of the code is below, but what I am having trouble with is the syntax for the async command. I tried making a task which indicates the calling of the sql query function but i get a compiler error saying it cannot convert the type into a task. Is there a way to do this by assigning my createReport function as a task and then awaiting for it to complete later on?

 if (Regex.IsMatch(Number,@"^\d+$") && Number.Length <= 3)
        {

      reportCreate.createReport(detailLength,detailDate,detailNumber);

   /* ^^ This was my original syntax but I want to make this asynchronous or in 
   a separate thread so I can continue working below.*/ 

   // do some comparing work here while the sql query/datatable is running.

   /* Wait for the datatable thread to finish and then continue with the code 
    below. Is there a way to do this using task and await? */ 



          }

2 Answers 2

2

You could do this by making your work run in the background and awaiting the results, ie:

var task = Task.Run(()=>reportCreate.CreateReport(...));

// Do other work

var report = await task;

That being said, this will only work if the CreateReport method is fine working on a background thread.

Also - be aware that async in a console application often behaves oddly, as there is no synchronization context to post back onto. This means that special care needs to be taken if you want to guarantee that things work properly. A simple way to handle this is to not use async/await, but instead just wait on the result:

var task = Task.Run(()=>reportCreate.CreateReport(...));

// Do other work

var report = task.Result; // Will block until first task is done
Sign up to request clarification or add additional context in comments.

6 Comments

Using async/await in a Console application is also a bit tricky.
@WouterdeKort Good point - missed that in the OP - added something to mention it.
Thanks i appreciate the advice! Can I ask another question though? The syntax seems to be accepted except for 'var report = await task;'. I am getting a 'Cannot assign void to an implicitly-typed local variable'. I wonder if what I have up top is wrong: static async void main(string[] args). can this not be void?
@user3494110 You'd need to make CreateReport either return some value, or just use await task (not var report =), since there is no return type...
One last question reed. I ended up using: var task = Task.Run(() => { reportCreate.createReport(storeNumber, businessDate, supplierNumber); }); //do other stuff here await task; however that function in the separate class I am calling, i need the datatable that it returns. How do I get it back?
|
1

The first thing i would advise you is to look if your ORM provider (Entity Franework, ADO.NET, etc) provides an async endpoint. If it does, you wont be needing the extra thread creation, as database work is primarily IO bound.

If it doesn't and you to execute this on a different thread, you may use the Task Parallel Librarys Task class to execute work on a ThreadPool thread:

if (Regex.IsMatch(Number,@"^\d+$") && Number.Length <= 3)
{
    var createReportTask = Task.Run(() => { reportCreate.createReport(detailLength,detailDate,detailNumber }));

    // do some comparing work here while the sql query/datatable is running.

    await createReportTask;
}

Note that when using this in a Console Application you have to make sure your Main method doesn't return, hence terminating you process.

I strongly advise you to look for true asynchronous endpoints, those which dont require using a new thread at all.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.