如何使用async / await

时间:2014-12-18 09:27:03

标签: c# parallel-processing task

我有以下情况:

我正在处理三个"繁重的工作"方法,结合异步我会这样做并行。但它不起作用,有人能告诉我,我还没有理解吗?

这是我的代码:

static void Main(string[] args)
    {
        var watch = new Stopwatch();
        watch.Start();

        var result = GetStringAsync();

        var time = watch.ElapsedMilliseconds;
    }

    static async Task<string> GetStringAsync()
    {
        var result = "";
        result += await H1();
        result += await H2();
        result += await H3();

        return result;

    }

    static async Task<string> H1()
    {
        Console.WriteLine("entered h1");
        Thread.Sleep(10000);
        return "1";
    }

    static async Task<string> H2()
    {
        Console.WriteLine("entered h2");
        Thread.Sleep(10000);
        return "2";
    }

    static async Task<string> H3()
    {
        Console.WriteLine("entered h3");
        Thread.Sleep(10000);
        return "3";
    }

4 个答案:

答案 0 :(得分:2)

不是使用同步阻塞的Thread.Sleep()来阻塞线程,而是使用await Task.Delay() - 这是异步的。

此外,await仍会等待每个方法完成。从每个方法中获取所有任务,然后等待所有任务完成:

static void Main(string[] args)
{
    var watch = new Stopwatch();
    watch.Start();

    var result = GetStringAsync(); 
    result.Wait();        

    var time = watch.ElapsedMilliseconds;

    Console.WriteLine(result.Result + ":" +  time);
}

static async Task<string> GetStringAsync()
{
    var result1 = H1();
    var result2 = H2();
    var result3 = H3();

    await Task.WhenAll(result1,result2,result3);

    return result1.Result + result2.Result + result3.Result;            
}

static async Task<string> H1()
{
    Console.WriteLine("entered h1");
    await Task.Delay(TimeSpan.FromSeconds(10));
    return "1";
}

static async Task<string> H2()
{
    Console.WriteLine("entered h2");
    await Task.Delay(TimeSpan.FromSeconds(10));
    return "2";
}

static async Task<string> H3()
{
    Console.WriteLine("entered h3");
    await Task.Delay(TimeSpan.FromSeconds(10));
    return "3";
}

答案 1 :(得分:2)

我想转介你this stackoverflow post

    async Task LongTask1() { ... }
    async Task LongTask2() { ... }
    ...
    {
       // Start the stopwatch

       var watch = new Stopwatch();
       watch.Start();

       // Do Async Tasks

       Task t1 = LongTask1();
       Task t2 = LongTask2();
       await Task.WhenAll(t1,t2); //now we have t1.Result and t2.Result          

       // Now we have the time it took to complete all the async tasks

       var time = watch.ElapsedMilliseconds;
    }

要完全了解async / await,请参阅this tutorial on MSDN

答案 2 :(得分:0)

在本守则中:

Task<string> getStringResult = GetStringAsync();

Thread.Sleep(5000) // some long run working

string result = await getStringResult;

基本上你得到的结果是在它之前和异步运行的地方分开的上下文中。

在之前的模型中,我们必须这样写:

class StringMaker
{
    GetStringAsync();
    event EventHandler<string> StringReceived;
}

然后像:

一样使用它
StringMaker sm = new StringMaker();
sm.StringReceived += sm_StringReceived;
sm.GetStringAsync();

和处理程序不在我们想要的上下文中:

void sm_StringReceived(string e)
{
    string result = e;
}

答案 3 :(得分:0)

好的,我想我已经明白了。 有人可以检查一下:

static void Main(string[] args)
{
    var task = GetNameAsync();
    task.Wait();

    var result = task.Result;
    Console.WriteLine(result);
}

static async Task<string> GetNameAsync()
{
    var first = FetchFirstNameAsync();
    var second = FetchLastNameAsync();

    Console.WriteLine("I'm first...");

    await Task.WhenAll(first, second);

    return first.Result + " " + second.Result;
}

private static async Task<string> FetchFirstNameAsync()
{
    Console.WriteLine("entered1");
    return await Task.Factory.StartNew(() =>
    {
        var counter = 0;

        for (var index = 0; index < 20000; index++)
        {
            Task.Delay(1);
            counter++;
            Console.WriteLine("handled1");
        }

        return counter.ToString(CultureInfo.InvariantCulture) + "First";
    });
}

private static async Task<string> FetchLastNameAsync()
{
    Console.WriteLine("entered1");
    return await Task.Factory.StartNew(() =>
    {
        var counter = 0;

        for (var index = 0; index < 20000; index++)
        {
            Task.Delay(1);
            counter++;
            Console.WriteLine("handled2");
        }

        return counter.ToString(CultureInfo.InvariantCulture) + "Last";
    });
}