Task.Factory.FromAsync和BeginX/EndX之间的区别

本文关键字:EndX 之间 区别 BeginX Factory FromAsync Task | 更新日期: 2023-09-27 18:09:47

当使用TcpClient的标准BeginRead和EndRead方法并使用Task.Factory.FromAsync时,我有非常相似的代码。

这里有一些例子…错误处理代码未显示。

Task.Factory.FromAsync:

private void Read(State state)
{
    Task<int> read = Task<int>.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<int> 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);
}

这两种方法都很好,但我对它们的区别很好奇。两者的代码行几乎相当,它们似乎都执行完全相同的功能,具有相同的效率。哪一个更好?您希望在产品代码中看到什么?

Task.Factory.FromAsync和BeginX/EndX之间的区别

我更愿意看到基于Task<T>的代码:

  • 它提供了更容易的合成;例如,编写一个方法很容易,它接受Task<T>任务的集合,并返回另一个任务,该任务表示这些任务的多数判决。同样,您可以等待,直到任务集合中的任何一个已经完成,等等。
  • 它提供了更灵活的继续运行的调度。
  • 它允许任务本身返回类型安全,并且比BeginRead返回的有点贫血的IAsyncResult类型更多的信息。
  • 指定错误处理和取消任务比使用Begin/End模型更简单。
  • Task<T>在c# 5中通过async/await得到了更好的语言支持-如果你的代码库已经普遍使用Task<T>,那么将更容易利用这个

基本上在。net 4上运行的现代代码中,Task<T>是表示正在进行的任务的惯用方法。与之前的尝试相比,这是一个更丰富的工作环境,如果你有机会,我会拥抱它。显然,如果您使用的是。net 3.5或更早版本,生活就有点困难了,但我假设,当您问这个问题时,Task<T>是一个选项…