我正在使用通用函数来执行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
答案 0 :(得分:2)
通常,是的,当您想要在没有其他机制可以利用的情况下进行异步调用时,您所概述的模式通常是可以接受的。
但是,对于WCF,您可以生成符合Asynchronous Design Pattern的合同。生成服务引用时,单击“高级”按钮,然后选择“生成异步操作”:
执行此操作时,将生成服务合同以返回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方法的另一个参数传递。