Home > Software design >  WPF Problem with drawing Image multiple times using Thread and Dispatcher.Invoke
WPF Problem with drawing Image multiple times using Thread and Dispatcher.Invoke

Time:01-21

I'm trying to draw stuff on Image control a bunch of times and I need it to be refreshed and viewable after each drawing, with user controls staying accessible, responsible and non-frozen. The drawing itself is pretty fast.

I used Thread with Dispatcher.Invoke but it doesnt seem to work. MainWindow becomes irresponsive until cycle of drawing finishes.

You may see that I tried 2 variants with cycle inside of Invoke and outside. Can someone give me advice on the problem, please?

EDIT: view is an object that draws image on Bitmap and returns it as source for Image control.

iView is that Image control on the MainWindow.

private void Draw()
{
    // setting size of image
    view.DataHeight = 500;
    view.DataWidth = TDRConnection.MAX_DATAPOINTS;
    view.Height = (int)gView.ActualHeight;
    view.Width = (int)gView.ActualWidth;

    //drawing     
    iView.Source = view.DrawPixels(connection.GetMeasurementData(),
        TDRConnection.MAX_SUPPORTED_CHANNELS,
        portColors);
}

private void LiveDrawingAS()
{
    Dispatcher.Invoke(() => {
        int safety = 0;
        for (; safety < 300 && doLiveDrawing; safety  ) {
            Draw();
            //Thread.Sleep(100);
        }
        MessageBox.Show($"Done {safety} drawings");
    });
}
private void LiveDrawingNAS()
{
    int safety = 0;
    for (; safety < 300 && doLiveDrawing; safety  ) {
        Dispatcher.Invoke(() => {
            Draw();
            //Thread.Sleep(100);                    
        });
    }
    MessageBox.Show($"Done {safety} drawings");
}

private void bLive_Click(object sender, RoutedEventArgs e)
{
    doLiveDrawing = true;
    new Thread(new ThreadStart(LiveDrawingAS)).Start();
}

private void bStop_Click(object sender, RoutedEventArgs e)
{
    doLiveDrawing = false;
}

EDIT2: I've put creating of bitmap outside of Invoke, and now MainWindow is responsive, but the Image control is empty, so its still no use:

    private void LiveDrawingNAS()
    {
        WriteableBitmap wbm;

        int safety = 0;
        for (; safety < 30 && doLiveDrawing; safety  ) {
            wbm = DrawBitmap();
            Dispatcher.Invoke(() => {
                iView.Source = wbm;
            });
        }
        MessageBox.Show($"Done {safety} drawings");
    }

Okay, so I found the solution. It requires Freeze for bitmap:

    private void LiveDrawingOutUI()
    {
        WriteableBitmap wbm;

        int safety = 0;
        for (; safety < 300 && doLiveDrawing; safety  ) {
            wbm = DrawBitmap();

            wbm.Freeze();
            Dispatcher.Invoke(() => {
                iView.Source = wbm;
            });
        }
        MessageBox.Show($"Done {safety} drawings");
    }

Cheers!

CodePudding user response:

Okay, so I found the solution. It requires Freeze for bitmap. Now my Image is renewed with new data while Window is responsive:

    private void LiveDrawingOutUI()
    {
        WriteableBitmap wbm;

        int safety = 0;
        for (; safety < 300 && doLiveDrawing; safety  ) {
            wbm = DrawBitmap();

            wbm.Freeze();

            Dispatcher.Invoke(() => {
                iView.Source = wbm;
            });
        }
        MessageBox.Show($"Done {safety} drawings");
    }

Cheers!

  •  Tags:  
  • Related