如果我有一个 .NET 4.5 异步任务方法,例如:
public async Task<String> GetData()
(...)
return await MyObject.GetSomethingAsynchronous();
然后在同步线程的其他地方(例如非异步方法),我称之为:
String myString = MyObject.GetData().Result;
这是安全的做法还是不好的做法?
如果我有一个 .NET 4.5 异步任务方法,例如:
public async Task<String> GetData()
(...)
return await MyObject.GetSomethingAsynchronous();
然后在同步线程的其他地方(例如非异步方法),我称之为:
String myString = MyObject.GetData().Result;
这是安全的做法还是不好的做法?
Task.Result
一般不建议打电话。一个更好的解决方案是await
将Task
包含方法更改为async
,允许异步代码通过代码库成长。
Task.Result
与相比有两个问题await
(除了它阻塞而不是异步等待的事实):
Task
需要特定线程(例如,UI 线程)来完成,但该线程在该线程上被阻塞Task
。我在我的博客上更详细地解释了这一点。async
都将被包装在一个 中AggregateException
,这使得异常处理更加复杂。await
将解开潜在的错误,让您使用更自然的catch(MyExceptionType)
.基本上是的。
从您的问题中,我了解到您认为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);
}
}