Я делаю свое первое приложение WPF, в котором я использую YouTube .NET API для загрузки видео на Youtube с помощью ResumableUploader.
Этот 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 paramètres increrects.
Source = mscorlib StackTrace: à System.Reflection.RuntimeMethodInfo.Invoke (Object obj, BindingFlags BBBINDERBTINBERTE)параметры, культура CultureInfo, логические skipVisibilityChecks) System.Delegate.DynamicInvokeImpl (Object [] args) ® System.Windows.Threading.ExceptionWrapper.InternalRealCall (обратный вызов делегата, объектные аргументы, Boolean isSingleParameter) ® System.Windows.WatchT(Источник объекта, обратный вызов делегата, аргументы объекта, логическое значение isSingleParameter, делегат catchHandler) à System.Windows.Threading.Dispatcher.WrappedInvoke (обратный вызов делегата, аргументы объекта, логический isSingleParameter, делегат catchHandler) à System.Windows.Threading.DispatcherOperation.InvokeImpl () à System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext (состояние объекта) à System.Threading.ExecutionContext.runTryCode (объект userData) à System.Runtime.CompilerHupTecTecTeuncEcuCunSunserCurebackoutCode, Object userData) à System.Threading.ExecutionContext.RunInternal (обратный вызов ExecutionContext executeContext, обратный вызов ContextCallback, состояние объекта) à System.Threading.ExecutionContext.Run (обратный вызов ExecutionContext executeContext, обратный вызов ContextCallback, состояние объекта) à System.Invoke () à System.Windows.Threading.Dispatcher.ProcessQueue () à System.Windows.Threading.Dispatcher.WndProcHook (IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean & handled) à MS.Winc.IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean и обрабатывается) à MS.Win32.HwndSubclass.DispatcherCallbackOperation (Object o) à System.Windows.Threading.ExceptionWrapper.InternalRealCall (обратный вызов делегата, аргументы объекта, Boolean isSingleParameter) à System.Windows.Threading.ExceptionWrapper.TryCatchWhen (источник объекта, обратный вызов делегата, аргументы объекта, Boolean isSingleParameter, делегат catchHandler) à System.Windows.Thread.WrappedInvoke (обратный вызов делегата, объектные аргументы, логическое значение isSingleParameter, делегат catchHandler) à System.Windows.Threading.Dispatcher.InvokeImpl (приоритет DispatcherPriority, тайм-аут TimeSpan, метод делегата, аргументы объекта, логический isSingleParameter), System.Wkepat.(Приоритет DispatcherPriority, метод делегата, объектный аргумент). MS.Win32.HwndSubclass.SubclassWndProc (IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) MS.Win32.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 (сборка сборки, аргументы String []) à System.AppDomain.ExecuteAssembly (сборка строк, аргументы сборки EvisionSecurity, строка []) à Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly () ® System.Threading.ThreadHelper.ThreadStart_Context (состояние объекта) ® System.Threading.ExecutionContext.Run (обратный вызов ExecutionContext executeContext, ContextCallback, состояние объекта) ® System.Threading.ThreadHelper.ThreadStart ()*
Спасибо за любую помощь.
Edit: Я только что узнал, что если я не использую Dispatcher и просто вызываю, задаю значение напрямую, он работает отлично!OnProgress вызывается в основном потоке пользовательского интерфейса?Как это может быть?