.net 使用threading.Task运行WCF方法

.net 使用threading.Task运行WCF方法,.net,multithreading,wcf,task-parallel-library,.net,Multithreading,Wcf,Task Parallel Library,我使用一个通用函数来执行wcf服务调用-请参见下文。 我只是想确保我做的事情是正确的: 最重要的要求是服务调用应该在单独的线程中执行。起初我想到Backgroundworker,然后决定使用线程 Task.Factory.StartNewFunction函数调用.Invokeserv? 并得到结果result=t.result 如果我这样做有什么区别: Dim t1作为ObjectFunction functionToCall.Invokeserv的新任务 t1.开始 结果=t1。结果 我应该考

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

最重要的要求是服务调用应该在单独的线程中执行。起初我想到Backgroundworker,然后决定使用线程 Task.Factory.StartNewFunction函数调用.Invokeserv? 并得到结果result=t.result

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

Dim t1作为ObjectFunction functionToCall.Invokeserv的新任务 t1.开始 结果=t1。结果

我应该考虑并行吗? 我错过了什么重要的事情吗

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


如果要在名为sync的方法内执行异步调用,则没有意义

我建议您将此方法设置为sync,删除与任务相关的代码,并改用Task/Backgroundworker调用ServiceCall方法

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

让它像这样使用:

var caller = new Caller();
caller.Done += { // Your data handling here };
caller.Call(Method1);
在这里,您可以稍微使用这个对象,将返回的方法逻辑传递给构造函数,甚至将lambda作为另一个参数传递给调用方法


一种简单的实现方法。

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

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

当您这样做时,将生成服务契约以返回实现开始/结束,而不是同步操作

与同步操作相比,这些操作更可取,因为它允许您释放在等待IO完成时会被阻塞的线程,这是一个硬件信号,而不是需要您保持线程运行的信号


然后,您可以在上调用以返回一个线程,该线程也不会阻止可用于异步等待/继续调用的线程。

您的代码在result=t.result处被阻止。因此,我认为没有理由使用Task而不是直接调用该方法。当访问任务的Result属性时,当前线程将等待任务完成。因此,您启动任务并等待它在下面一行完成。这不是Task类的用途。您只需将工作移动到另一个线程,但阻止第一个线程,因此您不会赢得任何东西。谢谢。根据你的说法,调用threadUI将被阻止,这与我想要的相反。那么,如何使用Task正确执行此操作?@svick该项目位于vb.net 4.0中,我在理解c时没有任何问题,但我无法在我的系统中使用它solution@melspring是的,我没有意识到你正在使用VB,尽管你展示了源代码。在这种情况下,您可以使用Visual Studio 2012附带的Visual Basic 2010 VB 10.0吗?它在异步调用方面有一些很大的改进。基于事件的异步模式eap>异步编程模型APM@JoanComasFdz基于任务的模式>所有这些。问题是,选中该框只会显示APM版本,而不是EAP版本;您可以从其中一个创建基于任务的模式。如果可以使用.net 4.5,则可以。否则EAP会更好、更简单。@JoanComasFdz基于任务的模式是在.NET4.0中引入的,而不是在.NET4.5中引入的。另外,EAP或异步模式是否更好还有争议,我个人不喜欢EAP模式。唯一确定的是,基于任务的模式是当前推荐的模式,优于所有其他模式。对,它也有4个版本。
var caller = new Caller();
caller.Done += { // Your data handling here };
caller.Call(Method1);