1

我有这个简单的代码,它异步启动一个方法。它使用任务TCS包装代码。

Task<int> DoWork()
{
    var source = new TaskCompletionSource <int>();
    Thread.Sleep(220);
    source.SetResult(9999999);
    return source.Task;
}

void Main()
{
    Console.WriteLine(1);

    var t1=Task.Factory.StartNew(()=>DoWork());
    t1.ContinueWith(_=>Console.WriteLine ("doing something different "));
    t1.ContinueWith(_=>Console.WriteLine ("finished , value is ="+_.Result.Result));

    Console.WriteLine(2);
    Console.ReadLine();
}

输出 :

1
2
doing somethign different  //those last 2 lines can be swapped
finished , value is =9999999

但是现在,我想把它转换成使用Task.FromResult<TResult>

这没有很好的记录 ,所以我想知道,如何将上面的代码转换为使用Task.FroResult

4

2 回答 2

2

最简单的使用方法FromResult是:

public Task<int> DoWork()
{
    return Task.FromResult(99999);
}

但它在功能上完全等同于:

var tcs = new TaskCompletionSource<int>();
tcs.SetResult(99999);
return tcs.Task;

所以它不会休眠 220 毫秒。对于“延迟”变体,最简单的方法是:

public async Task<int> DoWork()
{
    await Task.Delay(220);
    return 99999;
}

并且此版本的行为与您提供的示例足够接近。

于 2013-06-27T09:15:59.430 回答
1

In your code, you return the Task only after the synchronous wait is over, so your code is equivalent to:

Task<int> DoWork()
{
    Thread.Sleep(220);
    return Task.FromResult(9999999);
}

But if you returned the Task immediately and then blocked some other thread:

Task<int> DoWork()
{
    var source = new TaskCompletionSource<int>();
    Task.Run(() =>
    {
        Thread.Sleep(220);
        source.SetResult(9999999);
    });
    return source.Task;
}

(Note: I'm not saying you should do this in real code.)

This code couldn't be simulated by Task.FromResult(), because that always creates an already completed Task.

于 2013-06-27T12:53:01.570 回答