C# 如果使用泛型System.action()调用,如何从WCF调用返回值?

C# 如果使用泛型System.action()调用,如何从WCF调用返回值?,c#,wcf,C#,Wcf,为了减少代码量,我们的团队在StartProcess方法中加入了一个代码量,以便为来自单个方法的所有调用调用调用WCF实现。这一切都很好,但由于泛型方法的实际调用使用System.Action进行调用,因此它永远不会返回值,而且由于我正在进行的某个调用希望发出请求/回复,因此我无法获得该返回值 以下是处理WCF请求的通用方法: public static ProcessResultDC StartProcess<T>(T setupData, string processName,

为了减少代码量,我们的团队在StartProcess方法中加入了一个代码量,以便为来自单个方法的所有调用调用调用WCF实现。这一切都很好,但由于泛型方法的实际调用使用System.Action进行调用,因此它永远不会返回值,而且由于我正在进行的某个调用希望发出请求/回复,因此我无法获得该返回值

以下是处理WCF请求的通用方法:

public static ProcessResultDC StartProcess<T>(T setupData, string processName, Action<T> action, string exteriorAccountNumber, string companyCode) where T : IAmValidatable, IHaveAProcessGuid {

    var result = new ProcessResultDC { Status = ProcessStatusEnum.Accepted };
    // Do some authentication stuff here

    try {

        action(setupData);    // <-- This returns void, but I would like to return a string to the client

    } catch (Exception exc) {
        result.Status = ProcessStatusEnum.Error;
        result.Messages.Add(exc.Message);
    }
    return result;
}
即使我的createOnDemandDataDc实现返回字符串,结果变量也无法从操作调用中了解字符串


有更好的方法吗?或者我可以简单地执行Action()调用以外的操作来获取返回字符串吗?

您可以使用
Func
来允许回调向
StartProcess
调用方返回值,而不是对回调参数使用
Action
。但是,这需要将所有回调更改为返回值的函数。如果您只有一个需要返回回复的回调,那么这可能不是一个愉快的想法


另一种有点脏的方法可能是直接在CreateOnDemandDataDc回调函数中编写对当前活动OperationContext的响应。查看
OperationContext.Current.RequestContext.Reply
和相关属性/方法。

您可以使用
Func
允许回调向
StartProcess
调用方返回值,而不是对回调参数使用
Action
。但是,这需要将所有回调更改为返回值的函数。如果您只有一个需要返回回复的回调,那么这可能不是一个愉快的想法


另一种有点脏的方法可能是直接在CreateOnDemandDataDc回调函数中编写对当前活动OperationContext的响应。查看
OperationContext.Current.RequestContext.Reply
和相关属性/方法。

我也是这样做的。每个方面都需要两种方法—一种用于
操作
,另一种用于
函数

如果先为
Func
编写一个:

public static ProcessResultDC StartProcess<T, TResult>(
  T setupData,
  string processName,
  Func<T, TResult> fn,
  string exteriorAccountNumber,
  string companyCode
)
  where T : IAmValidatable, IHaveAProcessGuid
{
  var result = new ProcessResultDC { Status = ProcessStatusEnum.Accepted };

  // Do some authentication stuff here

  try
  {
    result.Result = fn(setupData);
  }
  catch (Exception exc)
  {
    result.Status = ProcessStatusEnum.Error;
    result.Messages.Add(exc.Message);
  }

  return result;
}

这也是我做AOP的方式。每个方面都需要两种方法—一种用于
操作
,另一种用于
函数

如果先为
Func
编写一个:

public static ProcessResultDC StartProcess<T, TResult>(
  T setupData,
  string processName,
  Func<T, TResult> fn,
  string exteriorAccountNumber,
  string companyCode
)
  where T : IAmValidatable, IHaveAProcessGuid
{
  var result = new ProcessResultDC { Status = ProcessStatusEnum.Accepted };

  // Do some authentication stuff here

  try
  {
    result.Result = fn(setupData);
  }
  catch (Exception exc)
  {
    result.Status = ProcessStatusEnum.Error;
    result.Messages.Add(exc.Message);
  }

  return result;
}

这很好,我接受了你的建议,想出了一些中间的东西。我重构了StartProcess代码,现在有了另一个方法StartProcessWithReturn,它实现了您使用Func的建议。很好!谢谢你的帮助。这太好了,我接受了你的建议,想出了一些办法。我重构了StartProcess代码,现在有了另一个方法StartProcessWithReturn,它实现了您使用Func的建议。很好!谢谢你的帮助。谢谢尼古拉斯,非常好!我将实现这个设计,谢谢。谢谢尼古拉斯,非常好!我将实现这个设计,谢谢。
public static ProcessResultDC StartProcess<T>(
  T setupData,
  string processName,
  Action<T> fn,
  string exteriorAccountNumber,
  string companyCode
)
  where T : IAmValidatable, IHaveAProcessGuid
{
  return StartProcess(
    setupData,
    processName,
    t => { fn( t ); return 0; },
    exteriorAccountNumber,
    companyCode
  );
}