0

我尝试学习 WCF,所以我使用了一个简单的 WCF 应用程序,From Source Stephen Cleary => async-wcf-today-and-tomorrow

这是代码片段:

简单合约:

[DataContract]
public class CalculatorFault
{
  [DataMember]
  public string Message { get; set; }
}

[ServiceContract]
public interface ICalculator
{

  [OperationContract]
  [FaultContract(typeof(CalculatorFault))]
  Task<uint> DivideAsync(uint numerator, uint denominator);
}

简单的服务实现:

public class Calculator : ICalculator
{
  public async Task<uint> DivideAsync(uint numerator, uint denominator)
  {
    try
    {
      var myTask = Task.Factory.StartNew(() => numerator / denominator);
      var result = await myTask;
      return result;
    }
    catch (DivideByZeroException)
    {
      throw new FaultException<CalculatorFault>(new CalculatorFault { Message = "Undefined result" });
    }
  }
}

来自客户的简单电话:

static class Program
{
  static async Task CallCalculator()
  {
    try
    {
      var proxy = new CalculatorClient();
      var task = proxy.DivideAsync(10, 0);
      var result = await task;
      Console.WriteLine("Result: " + result);
    }
    catch (FaultException<CalculatorFault> ex)
    {
      Console.Error.WriteLine("Error: " + ex.Detail.Message);
    }
  }

  static void Main(string[] args)
  {
    try
    {
      CallCalculator().Wait();
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
    }

    Console.ReadKey();
  }
}

它有效:当我尝试将一个数字除以零时,我从客户那里得到了异常。

但我想要做的是将 WCF 调用委托给其他函数,如旧回调函数。所以我在客户端尝试以下操作

async Task CallCalculator()
{
    try
    {
         var task = channel.DivideAsync(10, 0);
         task.ContinueWith(OnWorkCompleted); 
    }
   catch (FaultException<CalculatorFault> ex)
    {
        Console.Error.WriteLine("Error: " + ex.Detail.Message);
    }

}

void OnWorkCompleted(Task<uint> task)
{      
     var result = task.Result;
    Console.WriteLine("Result From Async: " + result);
}

这也有效,但是当我尝试除以零时,我没有得到任何异常,尽管服务抛出异常,但客户端没有结果。

为什么会发生这种情况?如何修复它以从客户端捕获异常?

4

1 回答 1

3

作为一般规则,不要ContinueWithasync代码中使用;你应该await改用。

当您调用时,您的代码实际上得到了一个异常task.Result,但是这个异常不能catchCallCalculator.

所以,我会做这样的事情:

async Task CallCalculator()
{
  try
  {
     var result = await channel.DivideAsync(10, 0);
     OnWorkCompleted(result); 
  }
 catch (FaultException<CalculatorFault> ex)
  {
    Console.Error.WriteLine("Error: " + ex.Detail.Message);
  }
}
于 2013-10-10T12:30:33.107 回答