У меня есть сервис, основанный на следующий контракте (в сокращенном виде):Почему мой WCF FaultException не обрабатывается?
[ServiceContract]
public interface ISchedulerService
{
[OperationContract]
void Process(bool isForced);
}
германа (ИМХО) часть реализации является:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, UseSynchronizationContext = false)]
public class SchedulerService : ISchedulerService
{
public async void Process(bool isForced)
{
try
{
var prevStatus = Status;
Status = SchedulerStatus.Processing;
await ProcessListings();
Status = prevStatus;
}
catch (Exception ex)
{
throw new FaultException(ex.Message);
}
}
private static Task ProcessListings()
{
throw new Exception("ProcessListings failed.");
return Task.Delay(5000);
}
}
Служба в настоящее время размещается в крошечном консольном приложении :
class Program
{
private static readonly SchedulerService Scheduler = SchedulerService.Instance;
private static ServiceHost schedulerHost;
protected static void OnStart()
{
try
{
if (schedulerHost != null)
{
schedulerHost.Close();
schedulerHost = null;
}
schedulerHost = new ServiceHost(Scheduler);
schedulerHost.Open();
Scheduler.Start();
}
catch (Exception ex)
{
//EventLog.WriteEntry("Exception: " + ex.Message);
throw;
}
}
}
И, наконец, клиент:
private readonly SchedulerServiceClient _proxy= new SchedulerServiceClient();
...
void ExecuteProcessNowCommand()
{
try
{
_proxy.Process(true);
}
catch (Exception ex)
{
if (exception is SchedulerException)
{
MessageBoxFacility.ProcessingError((SchedulerException)exception);
}
}
}
где SchedulerServiceClient
- это прокси-сервер, сгенерированный при добавлении ссылки на службу. До сих пор я успешно размещал WCF внутри живой службы Windows и тестировал функции без исключений. Все было нормально, пока я не добавил обработку исключений. Я знаю, что это сложный сценарий, но большинство примеров, которые я видел, показывают, что FaultException
по крайней мере был бы пойман общим обработчиком Exception
в клиенте. Мой отладчик заставляет меня угадать, что исключение даже не делает его прокси, и оно остается необработанным в коде MVC. Когда я нажимаю «продолжить», я заканчиваю на экране, говоря, что стек содержит только внешний код. Это трассировку стека для этого внешнего кода:
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__1(Object state)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()</ExceptionString></Exception></TraceRecord>
Это заставляет меня думать, что мое использование async
в службе MCV может мне играть определенную роль, но, возможно, это всего лишь невинная посредник. Пожалуйста, помогите мне попытаться определить, почему исключение даже не распространяется на клиента.
Исключение должным образом улавливается методом, ожидающим метода асинхронизации, то есть 'Process' блокирует исключение, созданное' ProcessListings'. «AppDomain» все еще кажется прекрасным, в то время как 'Process' выдает исключение, которое он ловит. – ProfK
@ProfK 'ProcessListings' не является методом async. Он просто возвращает задачу. «Процесс» - это метод «async», выдающий исключение, которое не было обнаружено. – i3arnon
Ага, спасибо! Я только что удалил всю асинхронность, и исключение попадает на клиент. Итак, должен ли я скорее создать задачу в 'Process' и' await' сгенерированный метод async в прокси? – ProfK