使用threading.Task运行WCF方法

时间:2012-09-26 07:12:19

标签: .net multithreading wcf task-parallel-library

我正在使用通用函数来执行wcf服务调用 - 请参阅下文。 我只是想确保我做的是正确的事情:

  • 最重要的要求是服务调用应该在单独的线程中执行。最初我想到了Backgroundworker然后决定使用Threading.Task所以它很简单 Task.Factory.StartNew(Function() functionToCall.Invoke(serv))
    并获得结果result = t.Result

  • 如果我这样做会有什么不同之处:

      

    Dim t1 As New Task(Of Object)(Function()functionToCall.Invoke(serv))
      t1.Start()
      结果= t1.Result

  • 我应该考虑Parallel吗?

  • 我错过了什么重要的事吗?

  

编辑:此功能位于客户端解决方案的ServiceProxy项目

Private Function ServiceCall(ByVal functionToCall As ServiceDelegate(Of IEmpService)) As Object
    Dim channel As New ChannelFactory(Of IEmpService)(_endPoint)
    Dim serv As IEmpService
    Dim result As Object = Nothing

    serv = channel.CreateChannel()

    Try
        Dim t As Task(Of Object) = Task.Factory.StartNew(Function() functionToCall.Invoke(serv))
        result = t.Result

    Catch exp As Exception 
        CustomLog.Detail(exp)

    Finally
        If channel.State = CommunicationState.Faulted Then
            channel.Abort()
        Else
            channel.Close()
        End If
    End Try

    Return result
End Function

2 个答案:

答案 0 :(得分:2)

通常,是的,当您想要在没有其他机制可以利用的情况下进行异步调用时,您所概述的模式通常是可以接受的。

但是,对于WCF,您可以生成符合Asynchronous Design Pattern的合同。生成服务引用时,单击“高级”按钮,然后选择“生成异步操作”:

Service Reference advanced options dialog

执行此操作时,将生成服务合同以返回IAsyncResult interface实施(Begin / End),而不是同步操作。

这些优先于同步操作,因为它允许您释放在等待IO完成时将被阻塞的线程(这是一个硬件信号,而不是需要您保持线程的东西)。

然后,您可以调用FromAsync method上的TaskFactory class来返回Task<TResult>(也不会阻止线程),可以用来等待/继续异步调用。

答案 1 :(得分:0)

你想在名为sync的方法中进行异步调用,这没有意义。

我建议您让此方法同步(删除与任务相关的代码)并使用Task / Backgroundworker来调用ServiceCall方法。

使用带有公共方法的新对象将异步调用封装到同步ServiceCall方法中,并使用Event在收到数据时返回数据。

让它像:

一样使用
var caller = new Caller();
caller.Done += { // Your data handling here };
caller.Call(Method1);

在这里,您可以使用此对象进行一些操作,将构造函数中的返回方法逻辑或甚至lambda作为Call方法的另一个参数传递。

实施Event-Based Asynchronous Pattern(EAP)的简便方法。