我最近看到一个项目使用后台工作程序进行一些操作(从其他Web服务获取数据)并使用事件将数据抛出到客户端.此项目是一个WCF服务,由另一个类库作为WCF客户端角色由ASP.NET网站使用,并将事件转发给应用程序.所有多线程系列让我很好奇.我已经看到这是一个basicHttpBinding绑定,并且该服务的唯一行为是UseSynchronizationContext = false,我发现他们在无法解释的异常之后添加了它,这是正常的:)
现在我要问basicHttpBinding的默认ConcurrencyMode.它们不应该使它成为可重入或这是默认行为吗?
这种情况是否会继续失败,因为如果WCF服务从客户端关闭,他们已经有一个无法解释的引用未设置为对象的实例?
我相信在WCF服务中使用多线程操作需要依赖IIS处理的ASP.NET项目,因为在WCF服务将数据返回到客户端类库并将其附加到页面之前,可以将页面发送到客户端.
你能讨论一下并解释你的想法吗?
当您需要这样的异步编程风格来通知WCF消费者在使用CallbackContracts和嵌入式WCF技术进行长时间操作后通知多线程操作时,应该更好吗?
需要澄清以纠正设计并有一些证明这是一个糟糕的服务架构,如果它是真实的,我怀疑!
谢谢.
最佳答案 它本身并不是糟糕的架构,但听起来它确实会造成许多可能的陷阱.
WCF客户端库将所有协调保留在ASP.NET应用程序中.如果ASP.NET应用程序没有检查是否已完成对WCF服务的调用,那么在使用变量设置来自服务的值以及其他此类竞争条件之前,它将面临使用变量的风险,除非明确设置某种协调方式对完成事件的初始调用.
我的建议是从System.Threading.Tasks命名空间(MSDN reference)重写WCF客户端异步方法以返回Task对象.通过这种方式,您可以分离调用WCF服务的后台处理,并使用Task的Result属性来确保服务已完成.
一个例子:
protected void Page_Load(object sender, EventArgs e)
{
Task<string> t = Task<string>.Factory.StartNew(() =>
{
return MyWcfClientClass.StaticAsyncMethod(MyArguments);
}
/* other control initialization stuff here, while the task
and WCF call continue processing in background */
/* Calling Result causes the thread to wait for the task to
complete as necessary, to ensure we have our correct value */
MyLabel1.Text = t.Result;
}