【问题标题】:Parallel.For & listcollectionviewParallel.For & listcollectionview
【发布时间】:2013-03-26 08:55:06
【问题描述】:

我有一个 listcollectionview,我想使用 Parallel.For 对其进行迭代

目前为止:

        public void HighlightLoggingLvl(
        LoggingLvl.ELoggingLvl loggingLvl, bool ebool) {
        Parallel.For(0, HighlighterCollectionView.Count, i => {
                 Log4NetLog cC =
                     HighlighterCollectionView.GetItemAt(i) as
                     Log4NetLog;

                 if (cC != null &&
                    cC.MyLoggingLvl.EloggingLvl == loggingLvl) {
                         if (ebool) {
                             cC.LogColour.SetColor(cC.MyLoggingLvl);
                          } else {
                                    cC.LogColour.Colour = Colors.Transparent;
                          }
                 }
         });
        HighlighterCollectionView.Refresh();
    }

我收到以下错误:

A first chance exception of type 'System.InvalidOperationException' occurred in      WindowsBase.dll
A first chance exception of type 'System.InvalidOperationException' occurred in     WindowsBase.dll
A first chance exception of type 'System.InvalidOperationException' occurred in mscorlib.dll
A first chance exception of type 'System.InvalidOperationException' occurred in mscorlib.dll
A first chance exception of type 'System.AggregateException' occurred in mscorlib.dll
A first chance exception of type 'System.AggregateException' occurred in mscorlib.dll
A first chance exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll
System.Windows.Data Error: 8 : Cannot save value from target back to source. BindingExpression:Path=Log4NetSearchEngineCompassLogView.Log4NetHighlighter.IsAllHighlighterEnable; DataItem='CompassLogView' (HashCode=57871897); target element is 'CheckBox' (Name=''); target property is 'IsChecked' (type 'Nullable`1') AggregateException:'System.AggregateException: One or more errors occurred. ---> System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.
 at System.Windows.Threading.Dispatcher.VerifyAccess()
 at System.Windows.Threading.DispatcherObject.VerifyAccess()
 at System.Windows.Data.CollectionView.VerifyRefreshNotDeferred()
 at System.Windows.Data.ListCollectionView.GetItemAt(Int32 index)
 at LogViewerViewModel.tools.highlighters.Log4NetHighlighter.<>c__DisplayClass1.<HighlightLoggingLvl>b__0(Int32 i) in c:\Users\Reza\Documents\Visual Studio 2012\Projects\Pallas informatik\LogViewerV1\LogViewerViewModel\src\tools\highlighters\Log4NetHighlighter.cs:line 193
 at System.Threading.Tasks.Parallel.<>c__DisplayClassf`1.<ForWorker>b__c()
 at System.Threading.Tasks.Task.InnerInvoke()
 at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)
 at System.Threading.Tasks.Task.<>c__DisplayClass10.<ExecuteSelfReplicating>b__f(Object param0)
 --- End of inner exception stack trace ---
 at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
 at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
  at System.Threading.Tasks.Task.Wait()
  at System.Threading.Tasks.Parallel.ForWorker[TLocal](Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Func`4 bodyWithLocal, Func`1 localInit, Action`1 localFinally)
   at System.Threading.Tasks.Parallel.For(Int32 fromInclusive, Int32 toExclusive, Action`1 body)
        at LogViewerViewModel.tools.highlighters.Log4NetHighlighter.HighlightLoggingLvl(ELoggingLvl loggingLvl, Boolean ebool) in c:\Users\Reza\Documents\Visual Studio 2012\Projects\Pallas informatik\LogViewerV1\LogViewerViewModel\src\tools\highlighters\Log4NetHighlighter.cs:line 190
 at LogViewerViewModel.tools.highlighters.Log4NetHighlighter.set_IsDebugHighlighterEnable(Boolean value) in c:\Users\Reza\Documents\Visual Studio 2012\Projects\Pallas informatik\LogViewerV1\LogViewerViewModel\src\tools\highlighters\Log4NetHighlighter.cs:line 59
   at LogViewerViewModel.tools.highlighters.Log4NetHighlighter.set_IsAllHighlighterEnable(Boolean value) in c:\Users\Reza\Documents\Visual Studio 2012\Projects\Pallas informatik\LogViewerV1\LogViewerViewModel\src\tools\highlighters\Log4NetHighlighter.cs:line 39
---> (Inner Exception #0) System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.
  at System.Windows.Threading.Dispatcher.VerifyAccess()
  at System.Windows.Threading.DispatcherObject.VerifyAccess()
  at System.Windows.Data.CollectionView.VerifyRefreshNotDeferred()
  at System.Windows.Data.ListCollectionView.GetItemAt(Int32 index)
  at LogViewerViewModel.tools.highlighters.Log4NetHighlighter.<>c__DisplayClass1.<HighlightLoggingLvl>b__0(Int32 i) in c:\Users\Reza\Documents\Visual Studio 2012\Projects\Pallas informatik\LogViewerV1\LogViewerViewModel\src\tools\highlighters\Log4NetHighlighter.cs:line 193
  at System.Threading.Tasks.Parallel.<>c__DisplayClassf`1.<ForWorker>b__c()
  at System.Threading.Tasks.Task.InnerInvoke()
  at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)
  at System.Threading.Tasks.Task.<>c__DisplayClass10.<ExecuteSelfReplicating>b__f(Object param0)<---

我该如何解决这个问题? (代码示例会很棒)

【问题讨论】:

    标签: c# wpf parallel-processing


    【解决方案1】:

    您应该在 UI 线程上调用您的操作。

    使用invoke method查看调度程序类

    Understanding dispatcher in WPF

    【讨论】:

      【解决方案2】:

      您不能使用并行处理来更新 UI 元素。只有应用程序的主线程有权访问 UI。可以在复选框上调用Invoke,但是对于您正在做的工作,并行执行它的意义何在?它不会给你带来任何性能。

      我建议只使用常规的 for 循环而不是 Parallel.For

      【讨论】:

      • 我不能使用常规的for,列表很大,用户界面冻结。
      • 您可能想知道拥有这么多复选框是否是好的 UI 设计,如果您对其进行迭代,UI 会冻结...无论哪种方式,您都无法通过并行执行来加快速度,即使如果你确实使用 Invoke。
      猜你喜欢
      • 1970-01-01
      • 2013-12-21
      • 1970-01-01
      • 2011-02-28
      • 1970-01-01
      • 2012-09-06
      • 2016-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多