2014-01-07 3 views
0

Я работаю над приложением, которое состоит из двух компонентов: клиентского приложения и службы 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), а затем следующая итерация цикла, зависящая от программы. Я подозреваю, что здесь я сталкиваюсь с какой-то тупиковой ситуацией, но я не могу понять, где я ошибаюсь.

Я могу изменить свою службу, поэтому каждая часть процесса отображается как метод, но я бы хотел избежать этого, если это возможно, поскольку я хочу попытаться сохранить кодирование клиента как можно более легким и сделать все в оказание услуг.

Любая помощь приветствуется.

+0

Дайте нам что-нибудь, чтобы мы смогли воспроизвести проблему на наших машинах. –

+0

какой тип привязки вы используете wshttpbinding или httpbinding или что? –

+0

@Julie, это wsHttpBinding.Я не думаю о проблемах с сервисом, поскольку у меня есть другой метод async, который делает намного более простой процесс и работает отлично. – Andrew

ответ

1

Я не уверен, что цель блокировки службы для ожидания вызова из пользовательского интерфейса. Кроме того, если это не однопоточный один экземпляр WCF-сервиса, поддерживающего состояние операции внутри службы, это вызовет головные боли.

Вам будет лучше обслуживать запись состояния операции в очередь сообщений или таблицу базы данных, которую пользовательский интерфейс может прослушивать или опросить. Если вы действительно хотите поддерживать состояние состояния в службе, вам понадобится словарь для отображения прогресса на конкретный вызов.

+0

Блокировка происходит из-за того, что возможно выполнить более одного элемента в службе до того, как мой клиент обнаружит ее, что означает, что индикатор выполнения будет неправильным. Тем не менее, мне нравится идея в очереди. Я попробую и вернусь к тебе. Благодарю. – Andrew

Смежные вопросы