tasks 参数包含一个空值
The tasks argument included a null value
我正在使用 mvc 5 并按照 this sample 生成数组任务。
我确定数据库至少包含 1 行查询。我想我遇到了 Task 的问题,因为它向我抛出错误消息
The tasks argument included a null value.
当我尝试时:
// I'm sure `cg` was not null and `type` was not empty
var cg = new List<string>();
var type = "";
var db = new MyDbContext();
var list = new List<TopicViewModels>();
if (cg != null && cg.Count > 0)
{
var tasks = new Task<List<TopicViewModels>>[13];
byte i = 0;
while (i < cg.Count)
{
string _cg = cg[i];
tasks[i] = Task.Run(async () =>
{
return await db.Topics.Where(m => m.Type == type && m.Category == _cg)
.ToListAsync();
});
i++;
}
var continuation = Task.WhenAll(tasks); //the tasks argument included a null value
// never go to this loop...
foreach (var topics in continuation.Result)
{
topics.ForEach(x => list.Add(x));
}
}
我已经设置断点来检查数组 tasks
,tasks[0]
是否不为空。已正确添加。
你能解释一下为什么吗?
更新:(基于@YacoubMassad 评论)
await Task.WhenAll(tasks); //same error here...
//never go to this loop, too...
foreach (var task in tasks)
{
//
}
更新 2:(基于@DavidPine 的回答)
if (cg != null && cg.Count > 0)
{
var tasks = new List<Task<List<TopicViewModels>>>();
cg.ForEach(x =>
{
tasks.Add(Task.Run(async () =>
{
return await db.Topics.Where(m => m.Type == type && m.Category == x)
.ToListAsync();
}));
});
foreach (var topics in await Task.WhenAll(tasks.ToArray()))
{
topics.ForEach(x => list.Add(x));
}
}
这里有几个问题:
1. 使用 Task
或 Task<T>
时,如果可用,请始终使用 async / await
,即;您正在使用 .NET 4.5。
2.调用Task.WhenAll(tasks)
时,可能数组中有任务为空。您需要为此检查并正确处理它。
3. 您需要等待所有时间以确保工作完成,await Task.WhenAll(tasks)
.
var cg = new List<string>();
var type = "";
var db = new MyDbContext();
var list = new List<TopicViewModels>();
if (cg != null && cg.Count > 0)
{
var tasks = new Task<List<TopicViewModels>>[13];
byte i = 0;
while (i < cg.Count)
{
string _cg = cg[i];
tasks[i] = Task.Run(async () =>
{
// Isn't it possible that the where clause filters out and returns null?
return await db.Topics
.Where(m => m.Type == type && m.Category == _cg)
.ToListAsync();
});
i++;
}
// Use await keyword to ensure that work is done
var continuation = await Task.WhenAll(tasks.Where(t => t != null).ToArray());
// never go to this loop...
foreach (var topics in continuation.Result)
{
topics.ForEach(x => list.Add(x));
}
}
您的代码中有几个问题。
首先,你使用查询数据库的自然异步方法,你不需要在线程池线程上执行,那是多余的,特别是在 ASP.NET 已经使用线程池线程来服务请求。
其次,您不是在等待 Task.WhenAll
返回的任务,而是在使用 Task.Result
.[=16 在 foreach
循环中迭代时同步阻塞=]
您的密码应该是:
var queryTasks = cg.Select(cg => db.Topics.Where(m => m.Type == type && m.Category == cg).ToListAsync());
return await Task.WhenAll(queryTasks);
请注意,EF DbContext
不是线程安全的,并且不允许在其上执行并发操作。如果是这种情况,您将需要 await
每个独立查询。
我正在使用 mvc 5 并按照 this sample 生成数组任务。
我确定数据库至少包含 1 行查询。我想我遇到了 Task 的问题,因为它向我抛出错误消息
The tasks argument included a null value.
当我尝试时:
// I'm sure `cg` was not null and `type` was not empty
var cg = new List<string>();
var type = "";
var db = new MyDbContext();
var list = new List<TopicViewModels>();
if (cg != null && cg.Count > 0)
{
var tasks = new Task<List<TopicViewModels>>[13];
byte i = 0;
while (i < cg.Count)
{
string _cg = cg[i];
tasks[i] = Task.Run(async () =>
{
return await db.Topics.Where(m => m.Type == type && m.Category == _cg)
.ToListAsync();
});
i++;
}
var continuation = Task.WhenAll(tasks); //the tasks argument included a null value
// never go to this loop...
foreach (var topics in continuation.Result)
{
topics.ForEach(x => list.Add(x));
}
}
我已经设置断点来检查数组 tasks
,tasks[0]
是否不为空。已正确添加。
你能解释一下为什么吗?
更新:(基于@YacoubMassad 评论)
await Task.WhenAll(tasks); //same error here...
//never go to this loop, too...
foreach (var task in tasks)
{
//
}
更新 2:(基于@DavidPine 的回答)
if (cg != null && cg.Count > 0)
{
var tasks = new List<Task<List<TopicViewModels>>>();
cg.ForEach(x =>
{
tasks.Add(Task.Run(async () =>
{
return await db.Topics.Where(m => m.Type == type && m.Category == x)
.ToListAsync();
}));
});
foreach (var topics in await Task.WhenAll(tasks.ToArray()))
{
topics.ForEach(x => list.Add(x));
}
}
这里有几个问题:
1. 使用 Task
或 Task<T>
时,如果可用,请始终使用 async / await
,即;您正在使用 .NET 4.5。
2.调用Task.WhenAll(tasks)
时,可能数组中有任务为空。您需要为此检查并正确处理它。
3. 您需要等待所有时间以确保工作完成,await Task.WhenAll(tasks)
.
var cg = new List<string>();
var type = "";
var db = new MyDbContext();
var list = new List<TopicViewModels>();
if (cg != null && cg.Count > 0)
{
var tasks = new Task<List<TopicViewModels>>[13];
byte i = 0;
while (i < cg.Count)
{
string _cg = cg[i];
tasks[i] = Task.Run(async () =>
{
// Isn't it possible that the where clause filters out and returns null?
return await db.Topics
.Where(m => m.Type == type && m.Category == _cg)
.ToListAsync();
});
i++;
}
// Use await keyword to ensure that work is done
var continuation = await Task.WhenAll(tasks.Where(t => t != null).ToArray());
// never go to this loop...
foreach (var topics in continuation.Result)
{
topics.ForEach(x => list.Add(x));
}
}
您的代码中有几个问题。
首先,你使用查询数据库的自然异步方法,你不需要在线程池线程上执行,那是多余的,特别是在 ASP.NET 已经使用线程池线程来服务请求。
其次,您不是在等待 Task.WhenAll
返回的任务,而是在使用 Task.Result
.[=16 在 foreach
循环中迭代时同步阻塞=]
您的密码应该是:
var queryTasks = cg.Select(cg => db.Topics.Where(m => m.Type == type && m.Category == cg).ToListAsync());
return await Task.WhenAll(queryTasks);
请注意,EF DbContext
不是线程安全的,并且不允许在其上执行并发操作。如果是这种情况,您将需要 await
每个独立查询。