无法启动后台任务因为"调用线程无法访问此对象,因为另一个线程拥有它。"

时间:2017-11-21 06:30:36

标签: wpf async-await

我有一个WPF应用程序,我在那里制作动画。我想将此动画保存为动画GIF。构建此GIF是一项耗时的操作,因此我不想在UI线程上执行此操作。

我使用的基本代码是这样的。

private async void SaveAnimationAsGIF(string fileName)
{
    const float frameRate = 25;

    var rtb = new RenderTargetBitmap(
        800, //width 
        400, //height 
        96, //dpi x 
        96, //dpi y 
        PixelFormats.Pbgra32 // pixelformat 
        );
    AnimationRenderer renderer = new AnimationRenderer();
    renderer.ViewportWidth = rtb.Width;
    renderer.ViewportHeight = rtb.Height;

    Grid grid = new Grid();
    grid.Width = rtb.Width;
    grid.Height = rtb.Width;
    grid.Background = Brushes.White;

    // Calculate the delay between the frames (in msec)
    int delay = (int)(1000 / frameRate);

    // Initialize the encoder
    AnimatedGifEncoder e = new AnimatedGifEncoder();
    e.Start(fileName);
    e.SetFrameRate(frameRate);

    for (double time = 0; time < 1; time += (double)delay / 1000) {
        grid.Children.Clear();
        renderer.CurrentTime = time;

        Path strokePath = new Path();
        strokePath.Data = renderer.StrokePath;
        strokePath.Stroke = Brushes.Blue;
        strokePath.StrokeThickness = 1.0;
        grid.Children.Add(strokePath);
        grid.Measure(new Size(rtb.Width, rtb.Height));
        grid.Arrange(new Rect(0, 0, rtb.Width, rtb.Height));
        rtb.Clear();
        rtb.Render(grid);
        await Task.Run(() => e.AddFrame(rtb));
    }

    e.Finish();
}

删除async / await和Task.Run这可以在UI线程上运行。使用这里显示的代码我得到一个异常&#34;调用线程无法访问此对象,因为另一个线程拥有它。&#34;执行Task.Run

我在这里做错了什么

编辑: 将任务行更改为

RenderTargetBitmap rtb1 = rtb.GetAsFrozen() as RenderTargetBitmap;
await Task.Run(() => e.AddFrame(rtb1));

做了这个伎俩。

0 个答案:

没有答案