向方法添加进度条时出错

时间:2013-08-27 17:52:50

标签: c# windows

我一直在使用c#

开发一个Windows商店项目

我有一个名为

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

当我尝试向此添加进度条时,它会给我一个错误

该应用程序调用了一个为不同线程编组的接口。 (来自HRESULT的异常:0x8001010E(RPC_E_WRONG_THREAD))

请帮我纠正此错误

感谢

这是我的整个代码

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.
    }
}

2 个答案:

答案 0 :(得分:1)

你应该:

  1. 避免使用async void
  2. 使用TAP命名模式(使Task - 返回方法以“异步”结尾。)
  3. 使用AsTask执行complex interop between TAP and WinRT asynchronous operations
  4. 这样的事情:

    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
        {
            ...
        }
    }
    

答案 1 :(得分:0)

您正尝试从非UI线程访问UI组件。

使用:

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

您无法从非UI线程访问UI组件,使用Invoke调用delegate将函数调用传递给拥有该组件的线程,而不是该线程调用传递的委托。