我有我的网络应用,可以构建报告。 mvc3上的Web应用程序。构建器是WCF服务
我使用线程池来自动生成报告
基本模型如下:
- Web应用程序发送报告生成请求
- WCF服务创建工作线程并将响应发送到服务接受工作的Web应用程序
- Web应用程序继续工作。
我需要:当WCF工作线程完成作业时,我需要通知 Web应用程序该作业已完成。
那么如何使用我的网络应用程序捕获回调。(我使用mvc 3)
你能建议最简单的方法来实现这个逻辑吗?
答案 0 :(得分:0)
有使用Comet或Reverse-Ajax的方法。这已在此处回答: Is there some way to PUSH data from web server to browser?
答案 1 :(得分:0)
有趣的问题。如果我了解您的要求,您需要允许用户在后台生成报告时继续他们的业务,然后最终通过AJAX向用户发送报告已准备好的通知。
我相信你正朝着正确的方向前进。我建议的是利用WCF异步回调。 MSDN上有一篇很好的入门文章here。回调事件处理程序应使用在最初将报告请求发送到WCF操作时创建的唯一缓存键来设置报告的缓存状态。
客户端通知可以使用报告状态轮询机制来实现,该机制使用AJAX启用的相同唯一缓存密钥定期检查报告的状态。
异步WCF回调的一个简单示例可以执行以下操作:
ReportServiceClient reportSvcClient = new ReportServiceClient();
Guid reportStatusKey = Guid.NewGuid();
reportSvcClient.GenerateReportCompleted += new EventHandler<GenerateReportCompletedEventArgs>(ReportStatusCallback);
reportSvcClient.GenerateReportAsync(reportStatusKey, <other operation paramters>);
// Set initial report status to False
// (recommend setting an appropriate expiration period)
Cache.Insert(reportStatusKey.ToString(), false);
// WCF callback static method which sets the report status in cache
static void ReportStatusCallback(object sender, GenerateReportCompletedEventArgs e)
{
Cache[e.ReportStatusKey.ToString()] = e.IsComplete;
}
...
public partial class GenerateReportCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs
{
private object[] results;
public GenerateReportCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) :
base(exception, cancelled, userState)
{ this.results = results; }
public Guid ReportStatusKey
{
get {
base.RaiseExceptionIfNecessary();
return ((Guid)(this.results[0]));
}
}
public bool IsComplete
{
get {
base.RaiseExceptionIfNecessary();
return ((bool)(this.results[1]));
}
}
}
客户端AJAX实现可以使用相同的ReportStatusKey以您认为合适的任何频率检查报告的缓存状态。
答案 2 :(得分:0)
为什么不使用svcutil / async为wcf服务生成异步代理。这样您就不需要在服务中使用自己的工作线程,客户只需注册回调即可。
答案 3 :(得分:0)
这可以帮助您: WCF Service with callbacks coming from background thread?
如果还不够,您必须对您的网络应用实施推送通知。
答案 4 :(得分:0)
WCF包含一些名为 完成回调 的内容。在这里,您的客户端有一个方法,只要异步操作完成,它就会要求WCF为您调用。
例如:
public class MyClient : IDisposable
{
BuilderClient _proxy = new BuilderClient();
public void CallAsync(object input)
{
_proxy.BeginBuildReport(input, Oncompletion, null);
}
void OnCompletion(IAsyncResult result)
{
object output = _proxy.EndBuildReport(result);
//Do whatever you want with your output here.
}
public void Dispose()
{
_proxy.Close();
}
}
这将允许您使用简单的事件驱动模型。