代码之家  ›  专栏  ›  技术社区  ›  Asik

WPF ProgressBar-TargetParameterCountException

  •  1
  • Asik  · 技术社区  · 14 年前

    我正在制作我的第一个WPF应用程序,在该应用程序中,我使用youtube.net API使用resumableuploader将视频上载到youtube。

    此ResumableUploader异步工作,并提供事件AsyncOperationProgress以定期报告其进度百分比。

    我想要一个显示这个进度百分比的进度条。以下是我的一些代码:

    void BtnUpload_Click(object sender, RoutedEventArgs e) {
        // generate video
    
        uploader = new ResumableUploader();
        uploader.AsyncOperationCompleted += OnDone;
        uploader.AsyncOperationProgress += OnProgress;
        uploader.InsertAsync(authenticator, newVideo.YouTubeEntry, new UserState());
    }
    
    void OnProgress(object sender, AsyncOperationProgressEventArgs e) {
        Dispatcher.BeginInvoke((SendOrPostCallback)delegate {
            PgbUpload.Value = e.ProgressPercentage;
        }, DispatcherPriority.Background, null);
    }
    

    其中pgbupload是我的进度条,其他标识符对于这个问题并不重要。

    当我运行这个程序时,OnProgress会被点击几次,然后我会得到一个TargetParameterCountException。我尝试了几种不同的异步调用方法的语法,但都不起作用。我肯定问题出在委托上,因为如果我把它注释掉,代码就可以正常工作(但是ProgressBar当然不会更新)。

    以下是异常详细信息(部分用法语表示):

    System.Reflection.TargetParameterCountException 未处理的消息=nombre de 参数–错误。
    源=mscorlib stacktrace: System.Reflection.RuntimeMethodInfo.Invoke(对象 obj、bindingFlags、invokeAttr、binder 活页夹,对象[]参数, 文化信息文化,布尔 SkipVisibility检查) system.delegate.dynamicinvokeimpl(对象[] ) System.Windows.Threading.ExceptionWrapper.InternalRealCall(委托 回调,对象参数,布尔值 ISsingleParameter) System.Windows.Threading.ExceptionWrapper.TrycatchWhen(对象 源,委托回调,对象 参数,布尔ISsingleParameter, 委托catchHandler) system.windows.threading.dispatcher.wrappedinvoke(委托 回调,对象参数,布尔值 IsingleParameter,委托 抓取处理程序) system.windows.threading.dispatcherOperation.invokeImpl()。 System.Windows.Threading.DispatcherOperation.InvokeinsecurityContext(对象 状态) system.threading.executioncontext.runtrycode(对象 用户数据) system.runtime.compilerServices.runtimeHelpers.executeCodeWithGuaranteedCleanup(Trycode 代码,cleanupcode backoutcode,对象 用户数据) System.Threading.ExecutionContext.RunInternal(ExecutionContext ExecutionContext,ContextCallback 回调,对象状态) System.Threading.ExecutionContext.Run(ExecutionContext ExecutionContext,ContextCallback 回调,对象状态) System.Windows.Threading.DispatcherOperation.Invoke()。 System.Windows.Threading.Dispatcher.ProcessQueue()。 system.windows.threading.dispatcher.wndprochook(intptr Hwnd,Int32消息,Intptr wParam,Intptr lparam,布尔值&已处理) ms.win32.hwndwrapper.wndproc(intptr Hwnd,Int32消息,Intptr wParam,Intptr lparam,布尔值&已处理) ms.win32.hwndSubclass.DispatcherCallbackOperation(对象 o) System.Windows.Threading.ExceptionWrapper.InternalRealCall(委托 回调,对象参数,布尔值 ISsingleParameter) System.Windows.Threading.ExceptionWrapper.TrycatchWhen(对象 源,委托回调,对象 参数,布尔ISsingleParameter, 委托catchHandler) system.windows.threading.dispatcher.wrappedinvoke(委托 回调,对象参数,布尔值 IsingleParameter,委托 抓取处理程序) system.windows.threading.dispatcher.invokeimpl(调度器优先级 优先级,时间跨度超时,委托 方法,对象参数,布尔值 ISsingleParameter) System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority 优先级,委托方法,对象参数) ms.win32.hwndsubclass.subclasswndproc(intptr hwnd,int32 msg,intptr wparam,intptr l参数) ms.win32.unsafenativemethods.DispatchMessage(消息& 味精 system.windows.threading.dispatcher.pushframeimpl(调度程序帧 框架) system.windows.threading.dispatcher.pushframe(调度程序帧 框架) system.windows.threading.dispatcher.run()。 System.Windows.Application.RunDispatcher(对象 忽略) System.Windows.Application.RunInternal(窗口 窗口) system.windows.application.run(窗口 窗口) system.windows.application.run()。 wpfApplication3.app.main()dans h:\razor\documents\Visual Studio 2010年\projects\wpfapplication3\wpfapplication3\obj\x86\debug\app.g.cs:ligine 零 System.AppDomain.下一个安全程序集(程序集 程序集,字符串[]个参数) system.appdomain.executeassembly(字符串 汇编文件,证据 assemblysecurity,string[]个参数) Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()。 System.Threading.ThreadHelper.ThreadStart_Context(对象 状态) system.threading.executioncontext.run(executioncontext ExecutionContext,ContextCallback 回调,对象状态) system.threading.threadhelper.threadstart()。 内感觉:

    谢谢你的帮助。


    编辑:我刚发现如果我不使用调度器,直接调用设置值,它会很好地工作!是否在主UI线程上调用了OnProgress?怎么会这样?

    1 回复  |  直到 14 年前
        1
  •  1
  •   Chad    14 年前

    上载程序(或任何异步组件)可以与创建它的线程同步。可能有多种方法可以做到这一点,但我以前见过的方法是这样的:

    public class ResumableUploader {
      private SynchronizationContext _syncContext;
      public event EventHandler<ProgressChangedEventArgs> OnProgressChanged;
    
      public ResumableUploader() {
        _syncContext = SynchronizationContext.Current; //Think of this as the current thread
      }
    
      private ReportProgressChanged(int progress) {
         if(OnProgressChanged != null) {
             _syncContext.Send(s => { OnProgressChanged(this, new ProgressChangedEventArgs(progress)); }, null);  //s is any data you want to pass in, here it is unused
         }
      }
    }
    

    或者,如果用户/客户机在实例创建时提供了同步上下文,则用户/客户机的灵活性稍高,但也更复杂:

    public ResumableUploader(SynchronizationContext syncContext)