0

From what i have read and found about the writablebitmap am i not able to change it in a different thread then the one that created it. But i should be able to created it on a diffrent thread then the UI thread, then freze it and parse it to the UI thread for display. Example: Thread cannot access the object

However when i do this, do it tell me "The calling thread cannot access this object because a different thread owns it." who is this, when i have frozen the bitmap?

 public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Timer imageTimer = new Timer(41);
            imageTimer.Elapsed += async (sender, args) =>
            {
                ImageSource image = await GetImage((int)Math.Ceiling(Image.Width), (int)Math.Ceiling(Image.Height));
                DispatcherHelper.CheckBeginInvokeOnUI(() => {
                    Image.Source = image;
                });
            };
            imageTimer.Start();
        }

        public Task<WriteableBitmap> GetImage(int width, int height)
        {
            return Task.Factory.StartNew(() =>
            {
                WriteableBitmap bitmap = BitmapFactory.New(width, height);
                using (bitmap.GetBitmapContext())
                {
                    bitmap.Clear(System.Windows.Media.Colors.AliceBlue);

                    Random rnd = new Random();
                    Color[] Colors = new Color[100];
                    for (int i = 0; i <= 99; i++)
                    {
                        Colors[i] = Color.FromRgb((byte)rnd.Next(0, 255), (byte)rnd.Next(0, 255),
                            (byte)rnd.Next(0, 255));
                    }

                    double size = width / 50;
                    for (int i = 0; i <= 49; i++)
                    {
                        int from = (int)Math.Ceiling(size * (double)i);
                        int to = (int)Math.Ceiling(size * (double)(i + 1)) - 1;
                        var color = Colors[i];

                        bitmap.DrawFilledRectangle(from, 0, to, height, color);
                    }
                }

                bitmap.Freeze();
                return bitmap;
            });
        }
    }

    public static class KasperWriteableBitMapExtentions
    {
        public static void DrawFilledRectangle(this WriteableBitmap bmp, int x1, int y1, int x2, int y2, Color color)
        {
            // Use refs for faster access (really important!) speeds up a lot!
            int w = bmp.PixelWidth;
            int h = bmp.PixelHeight;

            // Check boundaries
            if (x1 < 0) { x1 = 0; }
            if (y1 < 0) { y1 = 0; }
            if (x2 < 0) { x2 = 0; }
            if (y2 < 0) { y2 = 0; }
            if (x1 > w) { x1 = w; }
            if (y1 > h) { y1 = h; }
            if (x2 > w) { x2 = w; }
            if (y2 > h) { y2 = h; }

            for (int y = y1; y < y2; y++)
            {
                for (int x = x1; x <= x2; x++)
                {
                    bmp.SetPixel(x, y, color);
                }
            }
        }
    }
Community
  • 1
  • 1
Androme
  • 2,399
  • 4
  • 43
  • 82
  • Not sure why `Freeze` won't work here. Your approach seems too complicated anyway. The Timer does already run on a ThreadPool thread, so why do you need another Task? Alternatively, you may use a DispatcherTimer, which already runs in the UI thread and would thus save you the `CheckBeginInvokeOnUI` call. – Clemens Jan 20 '16 at 06:58
  • @Clemens If i used an DispatcherTimer would it run on the UI thread, and the await will block the UI thread until the Bitmap is done. The is just testing, in i run it without a task do i get the same result. – Androme Jan 20 '16 at 07:32
  • What's the stack trace for your exception? – Drew Noakes Jan 20 '16 at 13:36
  • Also what is the full type of your `Timer`? – Drew Noakes Jan 20 '16 at 13:36

0 Answers0