WPF mvvm backgroundworker UI displaying different results

只谈情不闲聊 提交于 2019-12-25 02:47:21

问题


So finally i managed to create a working BackgroundWorker.

I used the ReportProgress method to updated UI elements in this way:

 bw.ReportProgress(1, node);
 bw.ReportProgress(2, connection);
 bw.ReportProgress(3);
 bw.ReportProgress(4, system);

Where the connection is a model Object, this is my progress method:

 void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        if (e.ProgressPercentage == 1)       //update nodes
        {
            this.Network.Nodes.Add((NodeViewModel)e.UserState);
        }
        if (e.ProgressPercentage == 2)       //update connections
        {
            this.Network.Connections.Add((ConnectionViewModel)e.UserState);
        }
        if (e.ProgressPercentage == 3)
        {
            this.Network.Connections.Clear();
            this.Network.Nodes.Clear();
        }
        if (e.ProgressPercentage == 4)
        {
            MainNet.Systems.Add((Common.Model.System)e.UserState);
        }
    }

I have multiple objects to update so I used the percentage as a filter.

I'm getting different results every time i run the code, as if some of the data is not rendered correctly in the UI

The correct form of UI:

Not correct:


回答1:


If you need to synchronize your worker(s) to avoid reentrancy or a race, there are several different ways. You can try an approach like this...

    private static void ManageBackgroundWorkers()
    {
        BackgroundWorker backgroundWorker1 = new BackgroundWorker();
        BackgroundWorker backgroundWorker2 = new BackgroundWorker();
        BackgroundWorker backgroundWorker3 = new BackgroundWorker();
        backgroundWorker1.DoWork += (s, a) =>
        {
            /* do stuff*/
        };
        backgroundWorker2.DoWork += (s, a) =>
        {
            /* do some more stuff*/
        };
        backgroundWorker3.DoWork += (s, a) =>
        {
            /* do even more different stuff*/
        };
        backgroundWorker1.RunWorkerCompleted += (s, a) =>
        {
            //this.Network.Nodes.Add((NodeViewModel)e.UserState);
            backgroundWorker2.RunWorkerAsync();
        };
        backgroundWorker2.RunWorkerCompleted += (s, a) =>
        {
            //this.Network.Connections.Add((ConnectionViewModel)e.UserState);
            backgroundWorker3.RunWorkerAsync()
        };
        backgroundWorker3.RunWorkerCompleted += (s, a) =>
        {
            // finish remaining tasks here
        };
        /* start the queue */
        backgroundWorker1.RunWorkerAsync();
    }

Each worker signals a completion and its event handler simply starts the next worker in the series. It is not a massive difference in what you have, but it repackages the steps that you were using the 'Percentage' property for. Percentage is really a bad proxy for state anyway. Refactoring your code should take about 5 minutes.

An alternative method is to instrument the callback with an ManualResetEvent that signals each time it is called. And the ManualResetEven is waited upon in the worker after each call to the ReportProgress handler. Messier, less modular, but indeed workable.



来源:https://stackoverflow.com/questions/23548685/wpf-mvvm-backgroundworker-ui-displaying-different-results

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!