[英]Reporting progress on a WPF background worker running a WCF service
我正在开发一个包含两个组件的应用程序,一个客户端应用程序和一个WCF服务。 我需要在服务中调用的方法之一是一个长期运行的过程,并且我不想在运行时捆绑WPF UI,并且我还想在每个阶段完成时报告进度。 我创建了一个后台工作人员,如下所示:
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
// run the process
worker.RunWorkerAsync();
DoWork如下所示(代理是我与服务的连接):
proxy.CopyProjectToProduction(selectedItem, localDir, currentLabel);
此方法是一个6个阶段的过程,其中一些过程可能会花费毫秒,而另一些过程可能会花费10秒或更长时间。 我希望WPF进度栏能够执行的工作是报告每个阶段,然后通知服务已更新。 该服务需要在每个项目完成后停止,然后等待,直到它从UI收到已完成的确认。 为了尝试执行此操作,我首先创建了以下类型:
[DataContract]
public enum CopyProgress
{
[EnumMember]
Waiting = 0,
[EnumMember]
ConnectedToDev = 1,
// other enumerated types
}
在服务中,我有三种方法。 两个可公开访问的值(获取枚举值并将其重置)和另一个私有的值(由服务调用)如下:
public void WaitForStatusReset()
{
while (progress != CopyProgress.Waiting) { }
}
我的长时间运行过程的服务代码的一部分示例如下:
// establish a connection to dev and update progress
CreateTfsConnection(cDevServer);
progress = CopyProgress.ConnectedToDev;
WaitForStatusReset();
对服务中的6个项目中的每个项目重复此操作。 其想法是将其完成为正确的枚举类型,然后等待UI完成。 用户界面执行以下操作(在较大的循环内):
CopyProgress currentProgress = proxy.GetCopyStatus();
// if the progress has changed then we need to increment the progress bar
if (currentProgress != CopyProgress.Finished && currentProgress != progress)
{
worker.ReportProgress((int)progressIncrement);
proxy.ResetCopyStatus();
}
这应该不断循环以寻找进度变量中的更改,并且当确定它已更改时,它将更新进度栏,然后重置服务。 然后,服务将看到已将其重新设置为“等待”,并继续进行下一个操作。 实际上,将currentProgress变量设置一次(设置为Waiting),然后将程序挂起的下一次循环迭代。 我怀疑我在这里陷入了某种僵局,但是我无法弄清哪里出了问题。
我可以更改服务,以便将流程的每个部分都作为一种方法公开,但是如果可能的话,我希望避免这样做,因为我想尝试使客户端编码尽可能轻,并在服务中执行所有操作。
任何帮助表示赞赏。
我不确定阻止服务等待UI调用的目的是什么。 同样,除非这是单线程单实例WCF服务,否则维护该服务内操作的状态将引起麻烦。
将操作的状态写到UI可以监听或轮询的消息队列或数据库表中,将为您提供更好的服务。 如果您确实想维护服务中的状态,则需要使用词典将进度映射到特定的呼叫。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.