Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.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#异步异常包装_C#_.net_Asynchronous - Fatal编程技术网

C#异步异常包装

C#异步异常包装,c#,.net,asynchronous,C#,.net,Asynchronous,我一直在玩.NET4.6.1中的异步调用,我想知道一个期望异步方法但实际上是同步的接口的实现者抛出错误的正确方法是什么。例如: public interface ISomeInterface { Task ExecuteAsync(); } public class SomeClass : ISomeInterface { public Task ExecuteAsync() { return Task.FromException(new Excepti

我一直在玩.NET4.6.1中的异步调用,我想知道一个期望异步方法但实际上是同步的接口的实现者抛出错误的正确方法是什么。例如:

public interface ISomeInterface
{
    Task ExecuteAsync();
}

public class SomeClass : ISomeInterface
{
    public Task ExecuteAsync()
    {
        return Task.FromException(new Exception());
    }
}
我找到了
Task.FromException

所以这就是.NET4.6似乎仍然建议包装异常。但是,我可以只编写以下代码:

public class SomeClass : ISomeInterface
{
    public Task ExecuteAsync()
    {
        throw new Exception();
    }
}
当我使用try/catch块调用第二个实现时,客户机捕获了
异常
,我认为这就是为什么我们首先使用
Task.FromException
,而且它还包含对原始异常的整个调用堆栈(而方法一只有对客户端等待操作的堆栈跟踪)。看来第二种方法更好,但每个人似乎都在使用方法一。方法一现在是因为
async
的实现发生了变化而过时了,还是我遗漏了什么

我还注意到在堆栈跟踪中,
async
方法现在不会在调用之间引入任何额外的帧

正确的抛出错误的方法是来自期望异步方法但实际上是同步的接口的实现者

正如您所发现的,您可以直接抛出异常,也可以将异常放在返回的
任务上

请注意,在观察到异常的情况下,这种情况会发生变化:

var task = obj1.ExecuteAsync();
await task;
如果直接引发异常,则会在调用
ExecuteAsync
时引发异常。如果将异常放置在返回的任务上,则会在该任务被
wait
ed时引发异常。大多数情况下,调用方法后会立即引发任务,但并不总是如此(例如,在
任务中,当所有类型的场景都出现时)

对于异步(任务返回)API,返回的任务表示方法的执行。
async
-实现的API总是在返回的任务上放置任何异常。因此,我想说,任务返回API的期望是任务将接收异常

在的情况下,您可以选择任何一种方式。由于异常指示代码错误,因此在何时引发它并不重要。例如,LINQ to对象始终会立即引发boneheaded异常,而不是在枚举其返回的枚举数时


但是,对于所有其他类型的异常,他们肯定应该继续返回的
任务
。就我个人而言,我只是将所有异常都放在返回的
任务

上。啊哈,明白了!感谢您澄清这一点。