2014-01-11 4 views
2

Я пытаюсь создать конвертер видео в Gif, используя библиотеку WPF MediaKit (MediaDetector class) для извлечения видеофрагмента по времени. Я хочу запустить метод StartButton_OnClick асинхронно, используя async/await.Метод вызова асинхронно в C#

Я использую следующий код:

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() метод:

метод:

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 класс имеет public unsafe BitmapSource GetImage(TimeSpan position) метод.


Когда я нажимаю на StartButton, я получаю System.InvalidOperationException с сообщением «Вызывающий поток не может получить доступ к этому объекту, потому что другой поток владеет» в этой строке GetImage() метода (look this)

if (string.IsNullOrEmpty(m_filename)) 

Я новичок в многопоточном программировании. Как я могу решить эту проблему?

P.S. Извините за мой нехороший английский :-)

+1

Довольно уверен, что исключение составляет только одну строку раньше, где [Dispatcher.VerifyAccess] (http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.verifyaccess.aspx) является называется. Он проверяет, разрешен ли вызов метода из текущего потока, что, по-видимому, здесь не так. Вы можете обойти это ограничение, синхронно выполняя метод GetImage в потоке Dispatcher, то есть передавая его в [Dispatcher.Invoke] (http://msdn.microsoft.com/en-us/library/system.windows.threading. dispatcher.invoke.aspx). – Clemens

ответ

2

Возможно, вы сможете обойти async/await с помощью BeginInvoke. Так как это 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 может быть возможным, а также, хотя я бы не рекомендовал его.

Смежные вопросы