2015-06-21 936 views
0

此方法是从wpf主线程调用的。 投掷 - 不能隐式地将类型'bool'转换为'System.Threading.Tasks.Task'错误。 我在做什么错? DocCollection的类型为ObservableCollection。无法将类型'bool'隐式转换为'System.Threading.Tasks.Task'

Task TaskProcesQueue(SynchronizationContext _SyncContext) 
{ 
    return Task.Run(() => 
    { 
     if (DocCollection != null) 
     { 
      foreach (var item in DocCollection.ToList()) 
      { 
       ProcessCurrentDocument(item); 
       var t = Task.Run(() => DocCollection.Remove(item), _SyncContext)); 
      } 
     } 
    }); 
} 
+0

你肯定这是加工?您的右括号似乎不同步... – Noctis

+0

使用'Task.Run'从集合中删除项目(假设集合的大小合理)是多余的。 –

+0

@YuvalItzchakov不,不是。 OP正在这样做,以确保删除发生在正确的同步上下文中。直接调用'Remove'会在后台线程中执行,并且会导致它引发的任何事件在后台线程中运行。现在,OP在问题中的含义并不完全是正确的方式,因此错误信息,但您建议的方式也不是。 – hvd

回答

3

Task.Run没有超载接受SynchronizationContext。因此,当重载决议启动时,它无法找到合适的过载。如果删除同步上下文,它编译:

var t = Task.Run(() => DocCollection.Remove(item)); 

注意我建议你不要使用专用线程池线程从集合中删除的项目。这似乎是多余的。相反,我们已经致力于消除项目它的线程池线程的工作:

while (DocCollection.Count > 0) 
{ 
    ProcessCurrentDocument(item); 
    DocCollection.Remove(item); 
} 

编辑:

如果你想发布在SynchronizationContext

_SyncContext.Post(_ => { DocCollection.Remove(item) }, null); 
+1

我想他想使用同步上下文来更新UI线程上的原始集合。在这种情况下,您可以简单地使用同步上下文的Post方法。 – Dirk

+0

@Dirk这绝对有可能。如果这就是OP想要的,他应该在UI线程上代替IMO。 –

+0

这正是我想要的。我如何使用Post?一个例子,将不胜感激。 –

0

现在,你的代码是同步的,你的问题是,DocCollection.Remove(item)真的返回真/假,是指示删除是否成功与否的布尔方法。

如果你将删除整条线,所有将很好地工作,项目将被处理(但不会被删除)。

我想你想要的是实际使用运行任务的结果(注意它会阻止)。

查看official page on MSDN了解更多信息。

+0

我希望处理的项目立即被移除。你能建议一个兼容的语法吗? –