0

如果我有一个 .NET 4.5 异步任务方法,例如:

 public async Task<String> GetData()

 (...)

 return await MyObject.GetSomethingAsynchronous();

然后在同步线程的其他地方(例如非异步方法),我称之为:

 String myString = MyObject.GetData().Result;

这是安全的做法还是不好的做法?

4

2 回答 2

2

Task.Result一般不建议打电话。一个更好的解决方案是awaitTask包含方法更改为async,允许异步代码通过代码库成长。

Task.Result与相比有两个问题await(除了它阻塞而不是异步等待的事实):

  1. 您很容易陷入死锁情况,Task需要特定线程(例如,UI 线程)来完成,但该线程在该线程上被阻塞Task我在我的博客上更详细地解释了这一点。
  2. 从该方法抛出的任何错误async都将被包装在一个 中AggregateException,这使得异常处理更加复杂。await将解开潜在的错误,让您使用更自然的catch(MyExceptionType).
于 2012-12-17T14:46:41.007 回答
0

基本上是的。

从您的问题中,我了解到您认为Task哪个something executed in separate thread不一定正确。Asyc 机制比它更通用,它允许在您等待的同时做一些事情 - 线程作为一个结束,Web 请求返回值,文件系统读取文件,以及任何其他您想要的。这只不过是花哨的语法糖,让您不必为这样的模式所困扰:

void DoSomethingTimeConsumingThatWillNotBlockThisThread(Action onFinishContinue);

考虑这个简单的程序:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    protected override void OnLoad(EventArgs e)
    {
        GetPoint();
    }

    public async void GetPoint()
    {
        var point = await RetrivePointAsync();
        MessageBox.Show(point.ToString());
    }

    public Task<Point> RetrivePointAsync()
    {
        return Task.Factory.FromAsync<Point>(
             (callback, state) => new Handler(this, callback),
             x => ((Handler)x).Point, null);
    }
}

只是为了证明我的观点,我附加到事件中,我正在等待用户点击,所以不涉及线程。

class Handler : IAsyncResult
{
    AsyncCallback _calback;
    public Point Point { get; set; }
    public object AsyncState { get { return null; } }
    public bool CompletedSynchronously { get { return false; } }
    public bool IsCompleted { get; set; }

    public WaitHandle AsyncWaitHandle { get { return null; } }

    public Handler(Control control, AsyncCallback calback)
    {
        _calback = calback;
        control.MouseDown += control_MouseDown;
    }

    void control_MouseDown(object sender, MouseEventArgs e)
    {
        Point = e.Location;
        IsCompleted = true;
        _calback(this);
    }
}
于 2012-12-17T05:18:12.813 回答