Task.Factory.FromAsync和BeginX / EndX之间的区别?
当使用TcpClient中的标准BeginRead和EndRead方法并使用Task.Factory.FromAsync时,我有非常相似的代码。
以下是一些示例..error handling代码未显示。
Task.Factory.FromAsync:
private void Read(State state) { Task read = Task.Factory.FromAsync(state.Stream.BeginRead, state.Stream.EndRead, state.Bytes, state.BytesRead, state.Bytes.Length - state.BytesRead, state, TaskCreationOptions.AttachedToParent); read.ContinueWith(FinishRead); } private void FinishRead(Task read) { State state = (State)read.AsyncState; state.BytesRead += read.Result; }
使用BeginRead和EndRead标准使用回调:
private void Read(State state) { client.BeginRead(state.Bytes, state.BytesRead, state.Bytes.Length - state.Bytes.Read, FinishRead, state); } private void FinishRead(IAsyncResult async) { State state = (State)async.AsyncState; state.BytesRead += state.Stream.EndRead(async); }
这两个都很好,但我很好奇他们的差异。 两者的代码行几乎相同,它们似乎都执行完全相同的function并具有相同的效率。 哪个更好? 您更愿意在生产代码中看到什么?
我更愿意看到基于Task
的代码:
- 它更容易提供构图; 例如,编写一个接收
Task
任务集合并返回另一个代表这些任务的多数裁决的任务的方法相当容易。 同样,您可以等到任务集合中的任何一个完成,等等。 - 它提供了更灵活的连续运行位置安排。
- 它允许返回任务本身的类型安全性和比
BeginRead
返回的有点贫血的IAsyncResult
类型更多的信息。 - 使用任务指定error handling和取消比使用Begin / End模型更简单。
- 使用async / await,
Task
在C#5中获得更好的语言支持 – 如果你的代码库已经普遍使用Task
,那么利用它会更容易
基本上在.NET 4上运行的现代代码中, Task
是表示正在进行的任务的惯用方法。 与早期的尝试相比,这是一个更富裕的工作环境,如果你有机会,我会接受它。 显然,如果您使用的是.NET 3.5或更早版本,生活会有点困难,但我假设您在提问时, Task
是一个选项……