0

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

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

  • 如果我这样做有什么区别:

    将 t1 作为新任务(对象)(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
4

2 回答 2

2

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

但是,在 WCF 的情况下,您可以生成符合异步设计模式的合同。生成服务引用时,单击“高级”按钮,然后选择“生成异步操作”:

服务参考高级选项对话框

当您这样做时,将生成您的服务合同以返回IAsyncResult接口实现 ( Begin/ End) 而不是您的同步操作。

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

然后,您可以从那里调用上的FromAsync方法以返回一个(也不会阻塞线程),该方法可用于异步等待/继续调用。TaskFactoryTask<TResult>

于 2012-09-26T14:10:30.220 回答
0

您想在称为同步的方法中进行异步调用,这没有意义。

建议你让这个方法同步(去掉Task相关的代码),改用Task/Backgroundworker调用ServiceCall方法。

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

并让它像这样使用:

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

在这里,您可以稍微玩一下这个对象,在构造函数中传递返回方法逻辑,甚至将 lambda 作为另一个参数传递给 Call 方法。

一种实现基于事件的异步模式(EAP)的简单方法。

于 2012-09-26T14:08:43.200 回答