locked
Task without a return type

    Question

  • So I have this issue. I have a piece of code that is resource intensive, so I want to make it run asynchronously. I also want it to have no return type. So I wrote a very very simple piece of code that still shows me the error.

            
    private async void btnExecute_Tapped(object sender, TappedRoutedEventArgs e)
            {
                await this.RICode(2000);
            }
    
            public Task RICode(int secondNum)
            {
    
                for (int i = 0; i < secondNum; i++)
                {
                    //Resource intensive code that may lock up the GUI when run synchronously.
                }
            }

    This returns an error "....not all code paths return a value. So I have read a few forums and was told to make it an async task.

            private async void btnExecute_Tapped(object sender, TappedRoutedEventArgs e)
            {
                await this.RICode(2000);
            }
    
            public async Task RICode(int secondNum)
            {
    
                for (int i = 0; i < secondNum; i++)
                {
                    //Resource intensive code that may lock up the GUI when run synchronously.
                }
            }

    Suddenly the error disappears, and it seems fine. However, the problem here is that I like my code to be clean with no errors or warnings. While this may have ran successfully, I did get a warning "This async method lacks await....and will run asynchronously"

    Should I ignore the warning and leave the code as it is. It has no return value (finally) which is what I wanted, but has a warning.

    Thank you

    Sunday, September 07, 2014 6:01 PM

All replies

  • Remove the async keyword. It is separate from the Task return.

    Async means the function awaits another function that returns a Task. The Task return allows the function to be awaited. You'll also want to pop your loop onto a worker thread or you'll still block the UI. Async does not imply multi-threaded, although they do work well together.

    Sunday, September 07, 2014 6:13 PM
    Owner
  • You could just wrap the call to the the apparently synchronous method RICode in a Task in order to run it on a background thread and keep the UI thread responsive:

    private async void btnExecute_Tapped(object sender, TappedRoutedEventArgs e)
            {
                await System.Threading.Tasks.Task.Run(() => this.RICode(2000));
            }
    
            public void RICode(int secondNum)
            {
                for (int i = 0; i < secondNum; i++)
                {
                    //Resource intensive code that may lock up the GUI when run synchronously.
                }
            }
    

    The compiler won't generate any warning messages for the above code.

    Sunday, September 07, 2014 8:38 PM
  • @Magnus. The code works, but to a certain degree. It is not an awaitable code. I want to have the code run in the background, but the synchronous code to pause and wait for the asynchronous code to complete.

    Sunday, September 07, 2014 10:39 PM
  • >> I want to have the code run in the background, but the synchronous code to pause and wait for the asynchronous code to complete.

    The synchronous code in the RICode won't ever pause and it shouldn't either...why would you want a long-running operation to pause? The btnExecute_Tapped event handler will await the RICode method, or rather the task that wraps the RICode method, and continue the execution once it has finished. This is the way the async/await keywords work. They do not make a synchronous method asynchronous.

    And a Task created by the Task.Run method is exactly as awaitable as any other method that returns a Task. Synchronous methods that doesn't return a Task are not awaitable though so you either have to re-write your RICode method or wrap it in a Task as I have showed you.

    Monday, September 08, 2014 1:53 PM