开发者

c# wpf Thread is not terminating correctly

My problem is that I need a thread that is doing operations on Serialports. I implemented a worker class that is calling methods from other objects to read the values from the serial ports. The thread should do that while a private volatile attribute is true. If it is set to false, the loop is stopping. Within the loop I raise an event to pass eventargs to the GUI, so that it can be updated. In my WPF GUI I am catching the event and process the eventargs, when the workers attribue is still doing work (another volatile attribute).

Everything is working fine with the thread, when I do not fire the event in the worker class. But when i fire the event the thread is not going to stopped state sometimes(not always)

Code of worker:

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

                    if (measureD开发者_如何学Goispesner)
                    {
                        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 in 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;

...

What am I doing wrong?! How can I update my GUI threadsafe? I also tried Monitor to prevent other code calling the workerthread function again... Thank you in advance, Marc!


Thank you for the quick reply!

No, it is not really what I want, but is was a try to prevent executing GUI-code in the eventhandler because the Thread.Join() does not work when it tries to execute the GUI code. So I never have a stopped thread.

When passing the _continue flag with the eventargs, I can now prevent executing GUI code. That works fine till now.

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

But for interest, what do you mean with clearing the attribute ? Has it to be set to null anywhere?


But when i fire the event the thread is not going to stopped state sometimes(not always)

Ah, got to love throwing in a few extra negations. If I understand your code correctly, in your worker_ProcessChanged event handler, you are waiting for the thread to shut down (MyWorker.Continue becoming false). Is that really what you want? As far as I can see, you are not clearing Continue or _continue anywhere.

Maybe what you want in your event handler is something more along the lines of this?

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
}

If not, it may be prudent to go over your question another time, and phrase it more clearly.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜