【问题标题】:WPF ProgressBar - TargetParameterCountExceptionWPF ProgressBar - TargetParameterCountException
【发布时间】:2011-03-05 06:21:02
【问题描述】:

我正在制作我的第一个 WPF 应用程序,我使用 Youtube .NET API 通过 ResumableUploader 将视频上传到 Youtube。

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

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

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 未处理 Message=Nombre de 参数不正确。
来源=mscorlib 堆栈跟踪: à System.Reflection.RuntimeMethodInfo.Invoke(对象 obj、BindingFlags、invokeAttr、Binder 活页夹,Object[] 参数, CultureInfo 文化,布尔值 跳过可见性检查) à System.Delegate.DynamicInvokeImpl(Object[] 参数) à System.Windows.Threading.ExceptionWrapper.InternalRealCall(委托 回调,对象参数,布尔值 isSingleParameter) à System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object 源,委托回调,对象 args,布尔 isSingleParameter, 委托 catchHandler) à System.Windows.Threading.Dispatcher.WrappedInvoke(委托 回调,对象参数,布尔值 isSingleParameter,委托 捕获处理程序) à 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 执行上下文,上下文回调 回调,对象状态) à System.Threading.ExecutionContext.Run(ExecutionContext 执行上下文,上下文回调 回调,对象状态) à System.Windows.Threading.DispatcherOperation.Invoke() à System.Windows.Threading.Dispatcher.ProcessQueue() à System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd,Int32 消息,IntPtr wParam,IntPtr lParam, Boolean & 处理) à MS.Win32.HwndWrapper.WndProc(IntPtr hwnd,Int32 消息,IntPtr wParam,IntPtr lParam, Boolean & 处理) à MS.Win32.HwndSubclass.DispatcherCallbackOperation(对象 o) à System.Windows.Threading.ExceptionWrapper.InternalRealCall(委托 回调,对象参数,布尔值 isSingleParameter) à System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object 源,委托回调,对象 args,布尔 isSingleParameter, 委托 catchHandler) à System.Windows.Threading.Dispatcher.WrappedInvoke(委托 回调,对象参数,布尔值 isSingleParameter,委托 捕获处理程序) à System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority 优先级、TimeSpan 超时、委托 方法,对象参数,布尔值 isSingleParameter) à System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority 优先级、委托方法、对象 arg) à MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr l 参数) à MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& 味精) à System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame 框架) à System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame 框架) à 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:ligne 0 à System.AppDomain._nExecuteAssembly(Assembly 程序集,字符串 [] 参数) à System.AppDomain.ExecuteAssembly(字符串 汇编文件,证据 装配安全,字符串 [] 参数) à Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() à System.Threading.ThreadHelper.ThreadStart_Context(对象 状态) à System.Threading.ExecutionContext.Run(ExecutionContext 执行上下文,上下文回调 回调,对象状态) à System.Threading.ThreadHelper.ThreadStart() 内部异常:

感谢您的帮助。


编辑:我刚刚发现,如果我不使用 Dispatcher 而只是直接调用 set 值,它就可以正常工作! OnProgress 是否在主 UI 线程上调用?怎么可能?

【问题讨论】:

  • 能否提供TargetParameterCountException的StackTrace?

标签: c# wpf progress-bar


【解决方案1】:

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

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

或者,如果用户/客户端在实例创建时提供 SynchronizationContext,则对用户/客户端来说更灵活但也更复杂:

public ResumableUploader(SynchronizationContext syncContext)

【讨论】:

  • 感谢您的洞察力,我不知道。不“接受”答案,因为我仍然不明白为什么我的第一个方法(使用 Dispatcher)会抛出该异常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多