Quantcast
Channel: Windows Presentation Foundation (WPF) forum
Viewing all articles
Browse latest Browse all 18858

Wait event triggered problem

$
0
0

I have a window in which I need to create multiple BarGraphs from different datasets. For each dataset I create a StackPanel with a Busyindicator at startup, while the data is loaded. Each one loads in it's own modified Backgroundworker class.

I have a Dictionary for the Datasets, StackPanels, and BackGroundWorkers, so I can keep track of each, and can get the appropriate data for each StackPanel.

The Backgroundworker is creating a "List<Data>" from the datasets, which is used later to create the Bargraph from.So when the Backgroundworker completed I want to draw out the Graph on the StackPanel.

The GraphBuilder class will fire a SizeChanged event after the first draw since it needs to adjust the canvas for the new data.

The problem is that the event sometimes triggers after the backgroundworker already disposed itself, and than of course calls an error. So I tried to add a AutoResetEvent, but can't really get it to work.

Any suggestions appreciated.


This starts the Process:

//function to either start to laod data or show the panel if Checkbox checked, or hide panel
private void LoadData(CheckBox chb)
{
    string name = Helper.GetName(chb.Name, "__");

    if (chb.IsChecked == true)
    {
        StackPanel sp = (StackPanel)_stackList.GetStackPanel("StackPanel__" + name);

        if (sp != null)
        {
                    sp.Visibility = Visibility.Visible;
        }
        else
        {        

           //this loads the datasets in a backgroundworker
            StartBackgroundLoad(name);
            
            //this sets Busyindicator and starts backgroundworker that waits for other worker that the dataset loaded
            //so it can than process the data to List<Data> and draw BarGraph
            StartPlaceholderWorker(name);

        }                                
    }
    else
    {
        StackPanel sp = (StackPanel)_stackList.GetStackPanel("StackPanel__" + name);

        if(sp != null)
        {
            sp.Visibility = Visibility.Collapsed;
        }
    }
}

//function to start BackgroundWorker to build Bargraph
private void StartPlaceholderWorker(string sproc)
{
    try
    {                
        //if no placeholder(Busyindicator) exists create one
        if (!_stackList.StackPanelExists("StackPanel__" + sproc))
        {
            ControlUtility.CreatePlaceHolder(MainDock, sproc, _stackList.GetStackPanelList());
        }
               
        //create BackgroundWorkerExtended with events and add to _bWorker
        BackgroundControlBuildWorker bw = new BackgroundControlBuildWorker(sproc, MainDock, "AddBarGraph", new object[] { (Style)(this.Resources["myStyle"]) }, false, true);
         _bWorker.AddWorker(bw);
                
        bw.WorkerList = _bWorker;
        bw.DataList = _dataList;
        bw.RunWorkerAsync();
    }
    catch (Exception ex)
    {
        Helper.HandleError("", true, true, "Error (InfoPanel, StartPlaceholderWorker): " + ex.Message);
    }
}

Code Parts of my classes:

================ Parts Backgroundworker Class ==================


//Backgroundworker Complete event
private void backgroundControlBuildWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    BackgroundControlBuildWorker bw = (BackgroundControlBuildWorker)sender;

    try
    {
        string sproc = Helper.GetName(bw.Name, "__");


        if (e.Cancelled)
        {
            //do stuff
        }
        else if (e.Error != null)
        {
            //do stuff
        }
        else
        {
            object[] objList = (object[])e.Result;

            StackPanel sp = null;

            if (PanelList != null && PanelList.StackPanelExists("StackPanel__" + sproc))
            {
                sp = (StackPanel)PanelList.GetStackPanel("StackPanel__" + sproc);
            }
            else
            {
                sp = (StackPanel)ControlUtility.FindVisualChildByName<StackPanel>(Parent, "StackPanel__" + sproc);
            }
            
            WaitHandle = new System.Threading.AutoResetEvent(false);
            
            //AddBarGraph(objList, sp, sproc, WaitHandle, 350);

            GraphBuilder gb = new GraphBuilder(sproc);
            gb.WaitHandle = WaitHandle;

            StartThread(objList);

            waitHandle.WaitOne();
            Parent.RefreshUI();
        }
    }
    catch (Exception ex)
    {
        StackPanelControlRemove(Parent, Helper.GetName(bw.Name, "__"));
        Helper.HandleError("Die daten für '" + Helper.GetName(bw.Name, "__") + "' konnten leider nicht geladen werden!", true, true, "Error (BackgroundControlBuildWorker, backgroundControlBuildWorker_RunWorkerCompleted):" + ex.Message);
    }
    finally
    {
        if (bw.WorkerList != null) bw.WorkerList.RemoveWorker(bw.GetWorkerName());
        this.Dispose();
    }
}

private void StartThread(object[] objList)
{
    Thread newThread = new Thread(() => BuildGraph(objList));
    newThread.SetApartmentState(ApartmentState.STA);
    newThread.IsBackground = true;
    newThread.Name = "Thread" + Sproc;
    newThread.Start();    
}
        
private void BuildGraph(object[] objList)
{
    Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
    {
        gb.BuildGraph(objList, 350);
    }), System.Windows.Threading.DispatcherPriority.Background);
}

private void AddBarGraph(object[] objList, StackPanel sp, string sproc, AutoResetEvent waitHandle, double maxHeight = 250)
{
    try
    {
        ControlUtility.RemoveUIElement(sp, ControlUtility.FindVisualChild<BusyIndicator>(sp));
        GraphBuilder gb = new GraphBuilder(sproc);
        gb.WaitHandle = waitHandle;

        //BuildGraphOP bgOP = new BuildGraphOP(gb.BuildGraph);
        //bgOP.Invoke(objList, maxHeight);

        /*
        disp.BeginInvoke(new Action(() =>
        {
    gb.BuildGraph(objList, maxHeight);
        }));        
         * */

        gb.BuildGraph(objList, maxHeight);

        Canvas.SetLeft(gb.GraphCanvas, 0);
        Canvas.SetTop(gb.GraphCanvas, 0);

        gb.GraphCanvas.HorizontalAlignment = HorizontalAlignment.Left;
        gb.GraphCanvas.VerticalAlignment = VerticalAlignment.Top;

        sp.Children.Add(gb.GraphCanvas);
    }
    catch (Exception ex)
    {
        Helper.HandleError("", false, true, "Error (AddBarGraph): " + ex.Message);
    }
}

================ End Backgroundworker Class ==================


================ Parts GraphBuilder Class ==================
private Canvas cvs = null;
private Border bord = null;
private Grid baseGrid = null;

public AutoResetEvent WaitHandle { get; set; }
public bool DrawingFinished { get; set; }
        
public GraphBuilder(string name)
{
    try
    {
        DrawingFinished = false;
        Style style = new Style(typeof(Line));
        style.Setters.Add(new Setter(Line.StrokeProperty, new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFA7A7A7"))));

        cvs = new Canvas();
        cvs.Name = "Canvas_" + name;
        cvs.FlowDirection = FlowDirection.LeftToRight;
        cvs.SizeChanged += GraphCanvas_SizeChangedNew;
        cvs.MinWidth = 50;
        cvs.MinHeight = 50;
        cvs.Resources.Add(typeof(Line), style);

        bord = new Border();
        bord.Margin = new Thickness(0);
        bord.BorderThickness = new Thickness(1);
        bord.BorderBrush = Brushes.Black;
        bord.Child = cvs;

        baseGrid = new Grid();
        baseGrid.Name = "Grid_" + name;
        baseGrid.Children.Add(bord);
        //baseGrid.Background = Brushes.LightSlateGray;
    }
    catch(Exception ex)
    {
        Helper.HandleError(ex.Message, true);
    }        
}

public void BuildGraph(object[] lists, double maxCanvasHeight = 150, double vLineMarg = 25, double hLineMarg = 15, double offset = 10, double barWidth = 15, double barSpacing = 1)
{
    try
    {        
        cvs.Children.Clear();
                
        //do drawing stuff

        cvs.UpdateLayout();

        if (DrawingFinished && WaitHandle != null) WaitHandle.Set();
    }
    catch(Exception ex)
    {
        Helper.HandleError(ex.Message, true);
    }    
}

//SizeChanged will be called after first execution of BuildGraph to adjust to change on canvas

private void GraphCanvas_SizeChanged(object sender, SizeChangedEventArgs e)
{
    baseGrid.Width = CanvasWidth + VLineMarg + Offset;
    baseGrid.Height = CanvasHeight + TextHeight + HLineMarg + 50;
    /*
    Dispatcher.CurrentDispatcher.BeginInvoke((Action) (() =>
    {
        BuildGraph(itemLists, MaxCanvasHeight, VLineMarg, HLineMarg, Offset, BarWidth, BarSpacing);

    }));
     * */   
    
    DrawingFinished = true;
    BuildGraph(itemLists, MaxCanvasHeight, VLineMarg, HLineMarg, Offset, BarWidth, BarSpacing);    
}

================ End GraphBuilder Class ==================





Viewing all articles
Browse latest Browse all 18858

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>