【问题标题】:error while adding progress bar to a method向方法添加进度条时出错
【发布时间】:2013-08-28 02:32:45
【问题描述】:

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

【问题讨论】:

  • 听起来您正在尝试更新非 UI 线程上的进度条。发布您的所有代码。
  • 我已经添加了我的整个代码...请帮我添加进度条。谢谢

标签: c# windows


【解决方案1】:

你应该:

  1. 避免async void
  2. 使用TAP 命名模式(使您的Task-returning 方法以“Async”结尾)。
  3. 使用AsTaskcomplex interop between TAP and WinRT asynchronous operations

类似这样的:

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

【讨论】:

  • 嗨,我已经尝试了代码,但进度条仍然没有加载。如何更正它。谢谢
  • yes "var result" 表示不能将 void 分配给隐式类型的局部变量。并且也如上述代码行中所述...pb1.value=percent;不显示进度条加载。谢谢
  • 然后去掉“var result =”。
  • 即使是同样的事情..它没有加载进度条,当我尝试将“var progress”值赋予文本块时,它显示 System.Progress'1[system.double]在文本块中。
【解决方案2】:

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

使用:

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

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

【讨论】:

  • 嗨,对不起,我是一个初学者,你能详细说明一下这个概念吗?谢谢
  • 当我尝试输入您建议的相同代码时,它显示 INVOKEREQUIRED 不存在
猜你喜欢
  • 1970-01-01
  • 2019-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-28
  • 2021-07-08
相关资源
最近更新 更多