C# 在C中异步调用方法#

C# 在C中异步调用方法#,c#,.net,wpf,multithreading,asynchronous,C#,.net,Wpf,Multithreading,Asynchronous,我正在尝试创建视频到Gif转换器,使用库按时间提取视频帧。我想使用async/await异步运行StartButton\u OnClick方法 我正在使用以下代码: private async void StartButton_OnClick(object sender, RoutedEventArgs e) { if (_openFile != null && !String.IsNullOrEmpty(SaveToBox.Text)) {

我正在尝试创建视频到Gif转换器,使用库按时间提取视频帧。我想使用async/await异步运行
StartButton\u OnClick
方法

我正在使用以下代码:

private async void StartButton_OnClick(object sender, RoutedEventArgs e)
{
    if (_openFile != null &&
        !String.IsNullOrEmpty(SaveToBox.Text))
    {
        await new LocalVideoConverter(_openFile.FileName, _from*1000, _to*1000,
            SaveToBox.Text, InterpolationMode.Low, new System.Drawing.Size(320, 240))
            .StartConverting();
    }
    else
        MessageBox.Show("Choose video file and enter path for Gif");
}
StartConverting()
方法:

public override Task StartConverting()
{
    return Task.Run(() =>
    {
        Encoder.Start(GifPath);
        Encoder.SetDelay(Ival);
        Encoder.SetRepeat(0);
        for (double i = From; i < To; i += Ival)
        {
            var frame = GetFrame(TimeSpan.FromMilliseconds(i));
            frame = ResizeImage(frame);
            AddFrame(frame);
        }
        Encoder.Finish();   
    });
}
protected override Image GetFrame(TimeSpan ts)
{
    var bitmapSource = _mediaDetector.GetImage(ts);
    using (var outStream = new MemoryStream())
    {
        BitmapEncoder enc = new BmpBitmapEncoder();
        enc.Frames.Add(BitmapFrame.Create(bitmapSource));
        enc.Save(outStream);
        return new Bitmap(outStream);
    }
}
MediaDetector类还有
公共不安全位图源GetImage(TimeSpan位置)
方法


当我单击StartButton时,我得到一个System.InvalidOperationException,消息为“调用线程无法访问此对象,因为它属于另一个线程” 在
GetImage()方法()的这一行中

我是多线程编程的初学者。我怎样才能解决这个问题


顺便说一句,很抱歉我的英语不好:-)

您可以使用
BeginInvoke
绕过
async
/
wait
。既然是WPF,我想你可以写

 private void StartButton_OnClick(object sender, RoutedEventArgs e) {
    if (_openFile != null && !String.IsNullOrEmpty(SaveToBox.Text)) {
        this.Dispatcher.BeginInvoke(new Action(delegate() {
            LocalVideoConverter lvc =  new LocalVideoConverter(_openFile.FileName, _from*1000, _to*1000,
            SaveToBox.Text, InterpolationMode.Low, new System.Drawing.Size(320, 240));
            lvc.StartConverting();
        }));
    } else
        MessageBox.Show("Choose video file and enter path for Gif");
}

BackgroundWorker
也可以,尽管我不推荐它。

非常确定,异常只出现在调用where之前的一行。它检查是否允许从当前线程调用方法,这里显然不是这样。您可以通过在调度程序线程中同步执行GetImage方法来绕过该限制,即将其传递给调用。
 private void StartButton_OnClick(object sender, RoutedEventArgs e) {
    if (_openFile != null && !String.IsNullOrEmpty(SaveToBox.Text)) {
        this.Dispatcher.BeginInvoke(new Action(delegate() {
            LocalVideoConverter lvc =  new LocalVideoConverter(_openFile.FileName, _from*1000, _to*1000,
            SaveToBox.Text, InterpolationMode.Low, new System.Drawing.Size(320, 240));
            lvc.StartConverting();
        }));
    } else
        MessageBox.Show("Choose video file and enter path for Gif");
}