0
votes

This method is called from wpf main thread. Throwing - Cannot implicitly convert type 'bool' to 'System.Threading.Tasks.Task' error. What am I doing wrong? DocCollection is of type ObservableCollection.

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));
            }
        }
    });
}
2
you sure that's working? your closing brackets seem to be out of sync ... - Noctis
using Task.Run to remove an item from a collection (assuming the collection is of reasonable size) is redundant. - Yuval Itzchakov
@YuvalItzchakov No, it's not. The OP is doing that to make sure the removal happens in the right synchronisation context. Calling Remove directly would do it in the background thread, and would cause any events raised by it to run in the background thread as well. Now, what the OP has in the question isn't entirely the right way to do it, hence the error message, but the way you're suggesting isn't either. - user743382
@hvd The OP is currently using a non-existing overload. If his intention was to invoke Remove on the UI thread, consider my comment void :) - Yuval Itzchakov

2 Answers

3
votes

Task.Run has no overload accepting a SynchronizationContext. Hence, when overload resolution kicks in, it fails to find the appropriate overload. If you remove the synchronization context, it compiles:

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

Note i'd advise you not to use a dedicated threadpool thread to remove an item from a collection. That seems redundant. Instead, let the thread-pool thread already dedicated to removing items to it's job:

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

Edit:

If you want to post on the SynchronizationContext:

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

Now that your code is in sync, your problem is that DocCollection.Remove(item) is actually returning true/false, being a boolean method that indicates whether or not the remove succeeded or not.

If you'll remove that whole line, all will work nicely, and items will be processed (but not removed).

I think what you want is to actually use the Result of the running the task (note that it'll block though).

Have a look at the official page on MSDN for more.