c # wpf Тема не заканчивается правильно - PullRequest
0 голосов
/ 17 февраля 2011

Моя проблема в том, что мне нужен поток, который выполняет операции на Serialports. Я реализовал рабочий класс, который вызывает методы из других объектов для чтения значений из последовательных портов. Поток должен делать это, пока частный атрибут volatile имеет значение true. Если установлено значение false, цикл останавливается. Внутри цикла я создаю событие для передачи событийных событий в графический интерфейс, чтобы его можно было обновить. В моем WPF GUI я улавливаю событие и обрабатываю события, когда атрибут работника все еще выполняет работу (еще один изменчивый атрибут).

Все отлично работает с потоком, когда я не запускаю событие в рабочем классе. Но когда я запускаю событие, поток не собирается останавливаться иногда (не всегда)

Код работника:

public void StartWork()
    {
        int i = 0;
        while (this._continue)  
        {
            this.StillRunning = true;
                try
                {

                    if (measureDispesner)
                    {
                        Dispenser.GetStatus();
                    }
                    if (MeasureScale)
                    {

                        Dispenser.Scale.Weigh();
                    }

                    OnProgressChanged(new ProgressChangedArgs(Dispenser, Dispenser.Scale));
                    Console.WriteLine("Executed measuring " + i++.ToString() + "  ScaleWeight: " + Dispenser.Scale.Status.CurrentStableWeight.ToString());
                }
                catch (Exception e)
                {
                    //throw e.InnerException;
                }
                finally
                {
                   // System.Threading.Monitor.Exit(this);
                } 


        }
        Console.WriteLine("Stopped after: " + i++.ToString());

        this.StillRunning = false;


    }

Eventhandler в WPF GUI:

void worker_ProgressChanged(object sender, M5.Objects.Dispenser.ProgressChangedArgs e)
    {
        M5.Objects.Dispenser.Worker MyWorker = (M5.Objects.Dispenser.Worker)sender;
        while (MyWorker.Continue)
        {
            // Wait while the worker is still running -  code angs here
            //return;
        }
        System.IO.MemoryStream ms;// = M5.Support.ResourceManager.ResMan.ConvertImageToMemoryStream(M5.Support.ResourceManager.ResMan.BottleImage);


        if (this.objDispenser.IsAvalaible)
        {
            this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, (Action)delegate()
            {
                this.txtComPort.Text = e.DispenserPort;
                this.lblDispenserStatus_Dispenser.Content = e.DispenserMedikament;

...

Что я делаю не так ?! Как я могу обновить мой GUI threadsafe? Я также попытался использовать Monitor, чтобы другой код снова не вызывал функцию workerthread ... Заранее спасибо, Марк!


Спасибо за быстрый ответ!

Нет, это не совсем то, что я хочу, но это попытка предотвратить выполнение GUI-кода в обработчике событий, потому что Thread.Join () не работает, когда он пытается выполнить код GUI. Поэтому у меня никогда нет остановленной темы.

При передаче флага _continue вместе с аргументами событий я теперь могу предотвратить выполнение кода GUI. Это прекрасно работает до сих пор.

   void worker_ProgressChanged(object sender, M5.Objects.Dispenser.ProgressChangedArgs e)
    {
        if (e.StopUI)
        {
            return;
        }

Но для интереса, что вы имеете в виду при очистке атрибута? Должно ли оно быть равно нулю где-либо?

1 Ответ

0 голосов
/ 17 февраля 2011

Но когда я запускаю событие, поток иногда не собирается останавливаться, иногда (не всегда)

Ах, надо любить, добавив несколько лишних отрицаний.Если я правильно понимаю ваш код, в вашем обработчике событий worker_ProcessChanged вы ожидаете завершения потока (MyWorker.Continue становится ложным).Это действительно то, что вы хотите?Насколько я вижу, вы нигде не очищаете Continue или _continue.

Может быть, то, что вы хотите в своем обработчике событий, является чем-то еще в этом роде?

void worker_ProgressChanged(object sender, M5.Objects.Dispenser.ProgressChangedArgs e)
{
    M5.Objects.Dispenser.Worker MyWorker = (M5.Objects.Dispenser.Worker)sender;
    MyWorker.Continue = false;
    while (MyWorker.StillRunning)
    {
        // Wait here...
    }

    // Do something else
}

Если нет, то было бы разумно повторить ваш вопрос в другой раз и сформулировать его более четко.

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