BackgroundWorker oder (Dispatcher) - Vorgang bereits abgeschlossen ist, wenn dabei die ReportProgress
Benutze ich DispatcherTimer
weil ich muss ein Betrieb alle paar Minuten. In diesem rufe ich ein BackgroundWorker
um meine Arbeit zu machen, und verwenden Sie dann den dispatcher befestigt, um die timer zu aktualisieren, mein UI. Ich denke die Fehler, die ich bin immer zu tun hat mit dem timer, aber ich bin mir nicht sicher. Ist der dispatcher ausgeführt oder der backgroundworker? Wie kann ich das ReportProgress innerhalb der foreach?
Den Fehler:
Dieser Vorgang hat bereits
OperationCompleted auf Sie und
weitere Anrufe sind illegal.
dabei:
(sender as BackgroundWorker).ReportProgress((counterTotalSteps / 100) * counterOnStep);
Hier ist die vereinfachte:
DispatcherTimer dispTimer = new DispatcherTimer();
Dispatcher dispatcher = dispTimer.Dispatcher;
dispTimer.Tick += delegate {dispTimer_Tick(dispatcher); };
dispTimer.Interval = new TimeSpan(0, 0, 45);
dispTimer.Start();
private void DoWork(object sender,Dispatcher dispatcher)
{
int counterTotalSteps = PartialEmployees.Count();
int counterOnStep = 1;
dispatcher.BeginInvoke(new Action(() =>
{
AllEmployees.Clear();
//calling the ReportProgress here works
foreach (var item in PartialEmployees)
{
counterOnStep ++;
//part below throws the error
(sender as BackgroundWorker).ReportProgress((counterTotalSteps / 100) * counterOnStep);
AllEmployees.Add(item);
}
counterOnStep = 0;
}));
}
EDIT:
StackTrace:
at System.ComponentModel.AsyncOperation.VerifyNotCompleted()
at System.ComponentModel.AsyncOperation.Post(SendOrPostCallback d, Object arg)
at System.ComponentModel.BackgroundWorker.ReportProgress(Int32 percentProgress, Object userState)
at System.ComponentModel.BackgroundWorker.ReportProgress(Int32 percentProgress)
at testDispatcher.ViewModel.EmployeeListViewModel.<>c__DisplayClass7.<DoWork>b__6() in C:\Users\kozaj\Documents\Visual Studio 2010\Projects\testDispatcher\testDispatcher\ViewModel\EmployeeListViewModel.cs:line 91
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.ProcessQueue()
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.Run()
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at System.Windows.Application.Run()
at testDispatcher.App.Main() in C:\Users\kozaj\Documents\Visual Studio 2010\Projects\testDispatcher\testDispatcher\obj\x86\Debug\App.g.cs:line 50
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
- Was ist der stack-trace?
- Warum sind Sie mit einem BackgroundWorker, aber das tun all die Arbeit auf dem UI-thread?
- Dies ist nur Beispiel-code, um zu sehen, wenn ich dies korrekt funktioniert, bevor Sie Sie implementieren in andere Dinge. Das, was Teil würde Sie bewegen sich außerhalb der dipatcher? Auch diese Listen werden an das UI.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Abfolge der Ereignisse
Schlage ich vor, mit dispatcher.Aufrufen (die läuft es sofort) nur auf die Schritte, die tatsächlich UI-Interaktion.
ReportProgress
ruft internBeginInvoke
Bericht die Fortschritte. Die Nachricht, die er sendet, werden nur verarbeitet, wenn der UI-thread ist frei, nachdem Sie fertig sind.Da Ihre Arbeit im UI-thread ausgeführt, sollten Sie nicht verwenden ein BackgroundWorker überhaupt.
Statt, Sie sollten aktualisieren Sie die Fortschritt-bar direkt in der Schleife.
dispatcher.BeginInvoke
tut?BeginInvoke
sich selbst aufrufen. Sie sind nicht immer alle gut aus der BackgroundWorker-Klasse.RunWorkerCompleted
.Completed
.