Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.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#_Wcf_Exception Handling - Fatal编程技术网

C# 在发生未处理的异常后,是否可以将执行返回到失败的方法?

C# 在发生未处理的异常后,是否可以将执行返回到失败的方法?,c#,wcf,exception-handling,C#,Wcf,Exception Handling,我有一个ASP.NET网站,其中包含一些WCF服务。我已连接到应用程序错误事件,因此可以记录任何未处理的异常 我真正想做的是将执行传递回被调用的方法,这样我就可以向客户端返回一些合理的内容,而不是抛出FaultException 我知道我可以将每个单独的服务调用包装在一个try/catch块中,但这意味着在每个方法中都有大量的样板代码。我真正想要做的是有一个中央的catch-all方法,比如Application\u Error,但是允许单独的服务调用收回控制权并向客户端返回一些有意义的内容 这

我有一个ASP.NET网站,其中包含一些WCF服务。我已连接到应用程序错误事件,因此可以记录任何未处理的异常

我真正想做的是将执行传递回被调用的方法,这样我就可以向客户端返回一些合理的内容,而不是抛出FaultException

我知道我可以将每个单独的服务调用包装在一个try/catch块中,但这意味着在每个方法中都有大量的样板代码。我真正想要做的是有一个中央的catch-all方法,比如Application\u Error,但是允许单独的服务调用收回控制权并向客户端返回一些有意义的内容

这可能吗


另外,如果有人认为我做得不对,背景是我在我的C#WCF代码中实现。其思想是,如果出现异常,我将返回一个包含详细信息的适当对象,以及其他有用的内容。这是一种比让WCF服务抛出异常更可控的处理方式。

如果你想做类似ROP风格的事情,那么你可以做以下事情(Jeff Bridgman建议的Failable name)

首先创建抽象基类,如下所示

public abstract class Failable<T> {
}
public abstract class Failable {
}
您还没有完全实现您想要的,因为您在每个服务方法中仍然有一些样板代码,但很少。它不仅仅是方法上的一个属性,但是这种方法更易于实现,并且适用于任何级别,无论是存储库、业务逻辑、WCF服务、客户端等。attibute方法仅适用于WCF

这种方法的好处是,它让WCF服务(或其他服务)的使用者有责任检查服务调用是否成功,并采取适当的行动。这是一种函数式风格,并导致更健壮的编码,因为您几乎被迫不忽略异常,这与非函数式编程不同,在非函数式编程中,您可能只是在假设没有出错的情况下获取服务的结果。没关系,除非出了什么问题


希望有帮助。

这可以通过属性来完成。请参阅此处的类似问题(和公认答案):定义一个新类型,如
Failable
或其他类型,并将其作为内部函数调用的返回方法?“这样我就可以向客户端返回一些合理的内容,而不是抛出FaultException”-嗯,
FaultException
可以是您喜欢的最小值或详细值,也是建议返回到WCF客户端的错误,或者我应该说是SOAPclients@JeffBridgman这实际上就是我想要做的,但我正试图以一种避免将每个服务调用包装在try/catch块中的方式来做。我希望能够使用全局未处理事件处理程序,但随后将执行传递回服务方法,以便它可以返回一个可失败的对象。@MickyD FaultException的问题在于(根据我的经验),它们可能是脆弱的,有时包含有用的信息,有时不包含。有时客户机会得到它们,有时服务调用会无声地失败。我在看一些更健壮的东西,比如任选一个单子,这与杰夫·布里奇曼的建议相似。我只是想知道如何做到这一点,而不必将每一个服务调用都包装在自己的try/catch blockWow中,这太神奇了。这正是我想做的!我想这意味着我不再需要未处理的异常事件了?我可以向
DoFailableAction()
方法添加任何日志记录。再仔细想想,现在似乎永远不会捕获未处理的异常事件,因为DoFailableAction方法将处理它们。如果是这样的话,我想在那里放一些日志记录,在这种情况下,我想注入日志记录依赖项。这意味着DoFailableAction方法不能是静态的,因为包含的类将具有非静态依赖关系。有什么评论吗?再次感谢。@avrohmyisroel你说得对。我修改了代码,使方法成为非静态的,并添加了一条注释,以显示在何处添加日志记录。谢谢你指出这一点。谢谢,太好了!
public class Success<T> : Failable<T> {
  public Success(T value) {
    Value = value;
  }

  public T Value { get; set; }
}

public class Success : Failable {
}

public class Failure<T> : Failable<T> {
  public Failure(Exception value) {
    Value = value;
  }

  public Exception Value { get; set; }
}

public class Failure : Failable {
  public Failure(Exception value) {
    Value = value;
  }

  public Exception Value { get; set; }
}
public Failable<T> DoFailableAction<T>(Func<T> f) {
  Failable<T> result;
  try {
    T fResult = f();
    result = new Success<T>(fResult);
  }
  catch (Exception ex) {
    result = new Failure<T>(ex);
    // Do logging, etc here...
  }
  return result;
}

public Failable DoFailableAction(Action f) {
  Failable result;
  try {
    f();
    result = new Success();
  }
  catch (Exception ex) {
    result = new Failure(ex);
    // Do logging, etc here...
  }
  return result;
}
Failable<Person> p = failableHelpers.DoFailableAction(() => service.GetPerson(1));
if (p is Success<Person>) {
  Person p = ((Success<Person>)p).Value;
  Debug.WriteLine("Value is Success, and the person is " + p.FirstName + " " + p.Surname);
} else {
  Exception ex = ((Failure<Person>)p).Value;
  Debug.WriteLine("Value is Failure, and the message is " + ex.Message);
}
Person jim = new Person(1, "Jim", "Spriggs");
Failable saveResult = failableHelpers.DoFailableAction(() => service.Update(jim));