0

我一直在使用 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.
    }
}
4

2 回答 2

1

你应该:

  1. 避免async void
  2. 使用TAP命名模式(使您的Task-returning 方法以“Async”结尾)。
  3. 用于在 TAP 和 WinRT 异步操作之间AsTask进行复杂的互操作。

像这样的东西:

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
    {
        ...
    }
}
于 2013-08-27T18:32:45.720 回答
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使用 a调用delegate将函数调用传递给拥有该组件的线程,然后该线程调用传递的委托。

于 2013-08-27T17:54:32.810 回答