Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Task.Factory.fromsync和BeginX/EndX之间的区别是什么?_C#_.net_Asynchronous_Task Parallel Library - Fatal编程技术网

C# Task.Factory.fromsync和BeginX/EndX之间的区别是什么?

C# Task.Factory.fromsync和BeginX/EndX之间的区别是什么?,c#,.net,asynchronous,task-parallel-library,C#,.net,Asynchronous,Task Parallel Library,在使用TcpClient中的标准BeginRead和EndRead方法以及Task.Factory.FromAsync时,我有非常相似的代码 这里有一些例子。。未显示错误处理代码 Task.Factory.fromsync: private void Read(State state) { Task<int> read = Task<int>.Factory.FromAsync(state.Stream.BeginRead, state.Stream.EndRea

在使用TcpClient中的标准BeginRead和EndRead方法以及Task.Factory.FromAsync时,我有非常相似的代码

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

Task.Factory.fromsync:

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;
}
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);
}

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

我更希望看到基于任务的代码:

  • 它使构图更容易;例如,编写一个方法相当容易,该方法接受一组
    任务
    任务,并返回另一个代表这些任务大多数的任务。同样地,您可以等到任务集合中的任何一个任务完成,等等
  • 它提供了更灵活的延续运行位置调度
  • 它允许任务本身以类型安全的方式返回,并且比
    BeginRead
    返回的有点贫乏的
    IAsyncResult
    类型返回的信息多得多
  • 使用任务指定错误处理和取消比使用开始/结束模型更简单
  • Task
    使用async/await在C#5中获得了更好的语言支持-如果您的代码库已经普遍使用了
    Task
    ,那么利用这一点就会容易得多

基本上,在.NET4上运行的现代代码中,
Task
是表示正在进行的任务的惯用方式。这是一个比以前更丰富的工作环境,如果你有机会,我会欣然接受。显然,如果您使用的是.NET 3.5或更早版本,生活会有点困难,但我假设在您提问时,
任务是一个选项…

谢谢您的回答!不过我还是有点困惑。我知道BeginRead非常有效,因为回调使用IO完成端口,而不是阻塞。ContineRead在效率方面是否与EndRead相同,因为它不阻塞并且只在EndRead运行的同一时间运行?另外,您能否详细说明它如何支持更好的错误处理?我是否也必须在每个代码示例的
state.BytesRead+=
行上执行相同的try-catch操作?@RyanPeschel:是的,它不会阻塞-否则它将毫无意义。不,您不需要相同的try/catch,因为您可以指定一个continuation在出错时运行,另一个在取消时运行,另一个在成功时运行-请查看continuateWith的重载。您还可以测试任务的状态,而不只是尝试获取结果(查看task.Status)。基本上,这一切都要丰富得多。C#5中的异步支持非常棒。我正在检查重载,但我不太明白您的意思。当出现错误/取消时,如何指定要运行的方法?我想我可能已经找到了。。你会用不同的函数多次调用ContinueWith吗?第二个参数类似于
TaskContinuationOptions。如果你想在出现错误时运行所述方法,则只调用onfaulted
。@RyanPeschel:我在电话上无法详细说明,但请看TaskContinuationOptions。编辑:刚刚看到你的编辑;是的,这就是我说的。请注意,可以附加多个连续体。