下面是涉及的代码:
private static async Task DoRunInOrderAsync<TTaskSeed>(SemaphoreSlim sem, IObservable<TTaskSeed> taskSeedSource, CreateTaskDelegate<TTaskSeed> createTask, OnTaskErrorDelegate<TTaskSeed> onFailed, OnTaskSuccessDelegate<TTaskSeed> onSuccess) where TTaskSeed : class
{
var tasks = await taskSeedSource
.Select(taskSeed => GetPendingOrRunningTask(taskSeed, createTask, onFailed, onSuccess, sem))
.ToList()
.ToTask();
await Task.WhenAll(tasks);
}
private static async Task GetPendingOrRunningTask<T>(T taskSeed, CreateTaskDelegate<T> createTask, OnTaskErrorDelegate<T> onFailed, OnTaskSuccessDelegate<T> onSuccess,
SemaphoreSlim sem) where T : class
{
Exception exc = null;
await sem.WaitAsync();
try
{
var task = createTask(taskSeed);
if (task != null)
{
await task;
}
onSuccess(task, taskSeed);
}
catch (Exception e)
{
exc = e;
}
sem.Release();
if (exc != null)
{
onFailed(exc, taskSeed);
}
}
地点:
-
Select
是IObservable<TResult> Select<TSource, TResult>(this IObservable<TSource> source, Func<TSource, TResult> selector)
来自System.Reactive.Linq.Observable
-
ToList
是IObservable<IList<TSource>> ToList<TSource>(this IObservable<TSource> source)
来自System.Reactive.Linq.Observable
-
ToTask
是Task<TResult> ToTask<TResult>(this IObservable<TResult> observable)
来自System.Reactive.Threading.Tasks.TaskObservableExtensions
- System.Reactive.Linq 版本为 2.2.5.0
据我所知,一切都已构建,周围没有陈旧的二进制文件。该错误经常发生,但并非总是发生。
对于我的一生,我无法理解 tasks
列表可以包含 null
如果GetPendingOrRunningTask
方法是async Task
?
编辑
所以ToList
注入(inject)null
。如何?为什么?我做错了什么(除了以编程为生)?
最佳答案
您可能存在竞争状况。
.ToList()
调用List<T>
构造函数。代码是here .
如果 taskSeedSource
中的元素数量如果构造函数开始和结束之间的时间发生变化,您可能会得到不一致的列表。特别是查看第 94 行。
ICollection<T> c = collection as ICollection<T>;
if( c != null) {
int count = c.Count;
if (count == 0)
{
_items = _emptyArray;
}
else {
_items = new T[count];
c.CopyTo(_items, 0); /* it's possible there are now fewer elements in c */
_size = count;
}
}
关于c# - 任务列表中出现奇怪的空条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27412560/