error while adding progress bar to a method

0

i have been working on a windows store project using c#

i have a method called

void TranscodeProgress(IAsyncActionWithProgress<double> asyncInfo, double percent)
{
    pg1.Value=percent;
}

when i try to add a progress bar to this it gives me an error

The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))

please help me to correct this error

thanks

this is my entire code

private async void  Button_Click_1(object sender, RoutedEventArgs e)
{
    Windows.Storage.StorageFile source;
    Windows.Storage.StorageFile destination;

    var openPicker = new Windows.Storage.Pickers.FileOpenPicker();
    openPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
    openPicker.FileTypeFilter.Add(".mp4");
    openPicker.FileTypeFilter.Add(".wmv");

    source = await openPicker.PickSingleFileAsync();

    var savePicker = new Windows.Storage.Pickers.FileSavePicker();

    savePicker.SuggestedStartLocation =
            Windows.Storage.Pickers.PickerLocationId.VideosLibrary;

    savePicker.DefaultFileExtension = ".wmv";
    savePicker.SuggestedFileName = "New Video";

    savePicker.FileTypeChoices.Add("MPEG4", new string[] { ".wmv" });

    destination = await savePicker.PickSaveFileAsync();

    // Method to perform the transcoding.
    TranscodeFile(source, destination);
}

async void TranscodeFile(StorageFile srcFile, StorageFile destFile)
{
    MediaEncodingProfile profile =
        MediaEncodingProfile.CreateWmv(VideoEncodingQuality.HD1080p);


    MediaTranscoder transcoder = new MediaTranscoder();


    PrepareTranscodeResult prepareOp = await
        transcoder.PrepareFileTranscodeAsync(srcFile, destFile, profile);


    if (prepareOp.CanTranscode)
    {
        var transcodeOp = prepareOp.TranscodeAsync();
        transcodeOp.Progress +=
            new AsyncActionProgressHandler<double>(TranscodeProgress);
        //  p1.Value = double.Parse(transcodeOp.Progress.ToString());
        // txtProgress.Text = transcodeOp.Progress.ToString();
        transcodeOp.Completed +=
            new AsyncActionWithProgressCompletedHandler<double>(TranscodeComplete);
    }
    else
    {
        switch (prepareOp.FailureReason)
        {
            case TranscodeFailureReason.CodecNotFound:
                MessageDialog md=new MessageDialog("Codec not found.");
                await   md.ShowAsync();
                break;
            case TranscodeFailureReason.InvalidProfile:
                MessageDialog md1 = new MessageDialog("Invalid profile.");
                await md1.ShowAsync();
                break;
            default:
                MessageDialog md2 = new MessageDialog("Unknown failure.");
                await md2.ShowAsync();
                break;
        }
    }

    //txtDisplay.Text = a;
}

void TranscodeProgress(IAsyncActionWithProgress<double> asyncInfo, double percent)
{
}

void TranscodeComplete(IAsyncActionWithProgress<double> asyncInfo, AsyncStatus status)
{
    asyncInfo.GetResults();
    if (asyncInfo.Status == AsyncStatus.Completed)
    {
        // Display or handle complete info.
    }
    else if (asyncInfo.Status == AsyncStatus.Canceled)
    {
        // Display or handle cancel info.
    }
    else
    {
        // Display or handle error info.
    }
}
c#
windows
asked on Stack Overflow Aug 27, 2013 by user2712393 • edited Aug 27, 2013 by Stephen Cleary

2 Answers

1

You should:

  1. Avoid async void.
  2. Use the TAP naming pattern (make your Task-returning methods end in "Async").
  3. Use AsTask to do complex interop between TAP and WinRT asynchronous operations.

Something like this:

private async void Button_Click_1(object sender, RoutedEventArgs e)
{
    ...
    await TranscodeFileAsync(source, destination);
}

async Task TranscodeFileAsync(StorageFile srcFile, StorageFile destFile)
{
    MediaEncodingProfile profile =
        MediaEncodingProfile.CreateWmv(VideoEncodingQuality.HD1080p);
    MediaTranscoder transcoder = new MediaTranscoder();
    PrepareTranscodeResult prepareOp = await
        transcoder.PrepareFileTranscodeAsync(srcFile, destFile, profile);
    if (prepareOp.CanTranscode)
    {
        var progress = new Progress<double>(percent => { pg1.Value = percent; });
        var result = await prepareOp.TranscodeAsync().AsTask(progress);
        // Display result.
    }
    else
    {
        ...
    }
}
answered on Stack Overflow Aug 27, 2013 by Stephen Cleary
0

You are trying to access UI component from non UI Thread.

use:

void TranscodeProgress(IAsyncActionWithProgress<double> asyncInfo, double percent)
{
    if(InvokeRequired)
    {
        Invoke(new MethodInvoker() => TranscodeProgress(asyncInfo, percent));
        return;
    }
        pg1.Value=percent;
}

You cannot access UI components from non UI threads, Calling Invoke with a delegate passes the function call to thread that owns the component and than that thread call the passed delegate.

answered on Stack Overflow Aug 27, 2013 by Mayank • edited Aug 27, 2013 by Mayank

User contributions licensed under CC BY-SA 3.0