3

According to the following example from MSDN:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

// Add a using directive and a reference for System.Net.Http; 
using System.Net.Http;

namespace AsyncFirstExample
{
    public partial class MainWindow : Window
    {
        // Mark the event handler with async so you can use await in it. 
        private async void StartButton_Click(object sender, RoutedEventArgs e)
        {
            // Call and await separately. 
            //Task<int> getLengthTask = AccessTheWebAsync(); 
            //// You can do independent work here. 
            //int contentLength = await getLengthTask; 

            int contentLength = await AccessTheWebAsync();

            resultsTextBox.Text +=
            String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength);
        }


        // Three things to note in the signature: 
        //  - The method has an async modifier.  
        //  - The return type is Task or Task<T>. (See "Return Types" section.)
        //    Here, it is Task<int> because the return statement returns an integer. 
        //  - The method name ends in "Async."
        async Task<int> AccessTheWebAsync()
        { 
            // You need to add a reference to System.Net.Http to declare client.
            HttpClient client = new HttpClient();

            // GetStringAsync returns a Task<string>. That means that when you await the 
            // task you'll get a string (urlContents).
            Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");

            // You can do work here that doesn't rely on the string from GetStringAsync.
                DoIndependentWork();

            // The await operator suspends AccessTheWebAsync. 
            //  - AccessTheWebAsync can't continue until getStringTask is complete. 
            //  - Meanwhile, control returns to the caller of AccessTheWebAsync. 
            //  - Control resumes here when getStringTask is complete.  
            //  - The await operator then retrieves the string result from getStringTask. 
            string urlContents = await getStringTask;

            // The return statement specifies an integer result. 
            // Any methods that are awaiting AccessTheWebAsync retrieve the length value. 
            return urlContents.Length;
        }


        void DoIndependentWork()
        {
            resultsTextBox.Text += "Working . . . . . . .\r\n";
        }
    }
}

// Sample Output: 

// Working . . . . . . . 

// Length of the downloaded string: 41564.

How replace the async web request call:

Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com"); with my own code block (that will contain a simple for loop)? Like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

// Add a using directive and a reference for System.Net.Http; 
using System.Net.Http;

namespace AsyncFirstExample
{
    public partial class MainWindow : Window
    {
        // Mark the event handler with async so you can use await in it. 
        private async void StartButton_Click(object sender, RoutedEventArgs e)
        {
            // Call and await separately. 
            //Task<int> getLengthTask = AccessTheWebAsync(); 
            //// You can do independent work here. 
            //int contentLength = await getLengthTask; 

            int contentLength = await AccessTheWebAsync();

            resultsTextBox.Text +=
            String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength);
        }


        // Three things to note in the signature: 
        //  - The method has an async modifier.  
        //  - The return type is Task or Task<T>. (See "Return Types" section.)
        //    Here, it is Task<int> because the return statement returns an integer. 
        //  - The method name ends in "Async."
        async Task<int> AccessTheWebAsync()
        { 
            // GetStringAsync returns a Task<string>. That means that when you await the 
            // task you'll get a string (urlContents).
            Task<string> getStringTask = GetMyString(); // here

            // You can do work here that doesn't rely on the string from GetStringAsync.
                DoIndependentWork();

            // The await operator suspends AccessTheWebAsync. 
            //  - AccessTheWebAsync can't continue until getStringTask is complete. 
            //  - Meanwhile, control returns to the caller of AccessTheWebAsync. 
            //  - Control resumes here when getStringTask is complete.  
            //  - The await operator then retrieves the string result from getStringTask. 
            string urlContents = await getStringTask;

            // The return statement specifies an integer result. 
            // Any methods that are awaiting AccessTheWebAsync retrieve the length value. 
            return urlContents.Length;
        }


        void DoIndependentWork()
        {
            resultsTextBox.Text += "Working . . . . . . .\r\n";
        }
    }
}

    private Task<string> GetMyString()
    {
        string str = string.Empty;
        for (int i = 0; i < 1000000000; i++)
        {
            // compute str using simple c# code
        }
        // How to return str now?
    }
5
  • 1
    Well is GetMyString actually asynchronous in any useful way? If it's not, it's not going to work well when you use it with code which is expecting appropriate asynchronous code (i.e. it returns pretty much immediately, and the task will complete later). Commented Sep 19, 2014 at 14:32
  • 2
    What is your question exactly? Commented Sep 19, 2014 at 14:33
  • No, GetMyString is not asynchronous. But I still want to make the call asynchronous Commented Sep 19, 2014 at 14:35
  • 3
    @yazanpro, do you mean that you want it to run in another thread? That's not the same as being asynchronous... Commented Sep 19, 2014 at 14:37
  • Yes, I seem to want it to run in another thread. I must be confusing the two concept! Commented Sep 19, 2014 at 14:38

1 Answer 1

5

How to return str now

Like this:

private async Task<string> GetMyString()
{
    string str = string.Empty;
    for (int i = 0; i < 1000000000; i++)
    {
        // compute str using simple c# code
    }
    return str;
}

However, it doesn't really make sense, because the implementation of GetMyString isn't asynchronous; you never use await in it, and the compiler will warn you about it.

If you just want to run GetMyString in a separate thread, make it synchronous and run it with Task.Run:

private string GetMyString()
{
    string str = string.Empty;
    for (int i = 0; i < 1000000000; i++)
    {
        // compute str using simple c# code
    }
    return str;
}

...

Task<string> getStringTask = Task.Run(() => GetMyString());
Sign up to request clarification or add additional context in comments.

4 Comments

Using a separate thread is exactly what I need. However, in order to make the answer complete, referring to "because the implementation of GetMyString isn't asynchronous", can you please elaborate how to implement GetMyString in an asynchronous way? Also, please indicate how to prevent the compiler error caused by return str;
@yazanpro No, it's the idea of your implementation that isn't asynchronous. For example, if you're actually receiving data from a web server, that's an asynchronous I/O operation, and doesn't use up any threads. You're doing CPU work, so there's no opportunity to use asynchronous I/O, just parallelism (at best). The two are very different concepts, and the way Task and Task<T> are defined makes this rather confusing.
@yazanpro So the task returned by Task.Run is basically asynchronous I/O to the CPU worker thread it just created - but the actual work you're doing is still CPU work, not asynchronous I/O.
Implementing a method with the async keyword without using await raises a compiler warning. You could remove the async keyword and use "return Task.FromResult(str)" instead.

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.