如果我有.NET 4.5异步任务方法,例如:
public async Task<String> GetData()
(...)
return await MyObject.GetSomethingAsynchronous();
然后在同步线程中的其他位置(例如非异步方法),我称之为:
String myString = MyObject.GetData().Result;
这样做或做法不好吗?
答案 0 :(得分:2)
通常不建议拨打Task.Result
。更好的解决方案是await
Task
并将包含方法更改为async
,从而允许异步代码在代码库中成长。
与Task.Result
相比,await
存在两个问题(除了它阻止而不是异步等待的事实):
Task
需要特定线程(例如,UI线程)才能完成,但该线程在Task
上被阻止。我会更详细地解释这一点on my blog。async
方法引发的任何错误都将包含在AggregateException
中,这会使异常处理变得更加复杂。 await
将解包基础错误,允许您使用更自然的catch(MyExceptionType)
。答案 1 :(得分: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);
}
}