Нужна помощь с потоками WPF - PullRequest
2 голосов
/ 27 февраля 2010

Надеюсь, вы можете помочь.

Сценарий Приложение WPF, вызывающее службу wcf для покупки продуктов и т. Д. Клиент может выбрать 20 продуктов в пользовательском интерфейсе и нажать кнопку «Купить», теперь для каждого обрабатываемого продукта мне нужно сообщить о статусе EG («ОК», «Нет в наличии», «Занят» и т. Д.) У меня есть txtReportProgress, который привязан к BuyCommand.

Проблема Несмотря на то, что все работает нормально, я получаю уведомление о каждом обработанном продукте, но он синхронизируется и фактически не сообщает о шагах в правильном порядке. Я думаю, что это связано с тем фактом, что я НЕ реализовал многопоточность, но я не знаю, как это сделать. Я прочитал, я могу использовать "Диспетчер" ввода / вывода фонового работника, но не могу заставить его работать. Хороший пример, чтобы дать вам идею.

Можете ли вы помочь мне и дать несколько советов?

    ---CustomerViewModel
    public ICommand BuyCommand
    {
        get
        {
            if (BuyCommand == null)
            {
                BuyCommand = new RelayCommand(param => Buy(), param => CanBuy);
            }
            return BuyCommand;
        }
    }

    private  void Buy()
    {
        ReportProgress("Buying Progress is starting");

        ProductStatus status=myService.IsProductAvailable();

        myService.ProcessProducts();  //For each product that is processed service does a callback and NotificationReceivedfromService is fired.THIS WORKS!!            
        ReportProgress(status);

        var result =DoSomethingElse();

        ReportProgress(result);
    }
    void NotificationReceivedFromService(object sender, StatusEventArg e)
    {
        //update the UI
        ReportProgress(e.Message);
    }

     static bool CanBuy
    {
        get
        {
            return true; 
        } 
    }
    public string CustomerLog
    {
        get { return _customerModel.CustomerLog; }
        set
        {
            _customerModel.CustomerLog = value;
            base.OnPropertyChanged("CustomerLog");
        }
    }
    internal void ReportProgress(string text)
    {
        CustomerLog += text + Environment.NewLine;            
    }

Ответы [ 3 ]

0 голосов
/ 28 февраля 2010

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

Что касается Dispatchers и BackgroundWorkers, это очень разные звери:
Dispatcher.Invoke используется для обновления пользовательского интерфейса из потока, отличного от потока пользовательского интерфейса.
Фоновые работники инкапсулируют задачи, которые выполняются в фоновом режиме, но для удобства имеют события, которые генерируются в потоке пользовательского интерфейса, что делает ненужным использование вызова Dispatcher.Invoke.

Вы можете прочитать больше о BackgroundWorkers здесь

0 голосов
/ 01 марта 2010

Как уже упоминалось, CallBack является асинхронным, поэтому у вас возникнет проблема заказа. Можете ли вы организовать звонок в службу каким-либо образом, чтобы вернуть какой-либо токен или другой идентификатор, который поможет вам сообщить о ходе выполнения в правильном порядке? Что-то, что вы можете сортировать, возможно?

0 голосов
/ 27 февраля 2010

Что такое канал связи WCF? Вы делаете несколько запросов к службе параллельно? Я не могу понять из вашего кода, где вообще происходит многопоточность, но я предполагаю, что NotificationReceivedFromService является своего рода обратным вызовом?

В любом случае, если вы использовали что-то вроде Dispatcher.BeginInvoke, ваши вызовы должны выполняться в том порядке, в котором они были выполнены, если они имеют одинаковый приоритет диспетчера.

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

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