我正在开发一个由两个组件组成的应用程序,一个客户端应用程序和一个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完成。 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变量设置一次(等待),然后是程序挂起的循环的下一次迭代。我怀疑我在这里陷入某种僵局,但我无法解决我出错的地方。
我可以更改我的服务,因此流程的每个部分都作为一种方法公开,但我想尽可能避免这种情况,因为我想尽量保持客户端编码尽可能轻,并在服务中做所有事情
任何帮助表示感谢。
答案 0 :(得分:1)
我不确定阻止服务等待来自UI的调用的目的是什么。此外,除非这是单线程单实例WCF服务,否则维护服务中的操作状态将导致令人头疼。
通过将操作的状态写入UI可以侦听或轮询的消息队列或数据库表,可以更好地服务。如果你真的想在服务中保持状态状态,你需要一个字典来将进度映射到特定的呼叫。