Я работаю над приложением, которое состоит из двух компонентов: клиентского приложения и службы WCF. Один из методов, которые мне нужно вызвать в моей службе, - это длительный процесс, и я не хочу связывать интерфейс WPF во время его работы, и я также хотел бы сообщить о прогрессе по мере завершения каждого этапа. Я создал фон работника следующим образом:Отчет о прогрессе в фоновом работнике WPF, выполняющем службу WCF
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 мог сделать, это сообщить о каждом из этих этапов, а затем сообщить об обновленной службе. Служба должна быть остановлена после завершения каждого элемента и дождаться получения подтверждения от пользовательского интерфейса, который он завершил. Чтобы попытаться сделать это, я сначала создал следующий тип:
[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 пунктов обслуживания. Идея состоит в том, что она завершит работу над правильным перечисляемым типом, а затем дождитесь завершения пользовательского интерфейса. Пользовательский интерфейс делает следующее (внутри больший цикла):
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), а затем следующая итерация цикла, зависящая от программы. Я подозреваю, что здесь я сталкиваюсь с какой-то тупиковой ситуацией, но я не могу понять, где я ошибаюсь.
Я могу изменить свою службу, поэтому каждая часть процесса отображается как метод, но я бы хотел избежать этого, если это возможно, поскольку я хочу попытаться сохранить кодирование клиента как можно более легким и сделать все в оказание услуг.
Любая помощь приветствуется.
Дайте нам что-нибудь, чтобы мы смогли воспроизвести проблему на наших машинах. –
какой тип привязки вы используете wshttpbinding или httpbinding или что? –
@Julie, это wsHttpBinding.Я не думаю о проблемах с сервисом, поскольку у меня есть другой метод async, который делает намного более простой процесс и работает отлично. – Andrew