繁体   English   中英

tasks参数包含null值

[英]The tasks argument included a null value

我正在使用mvc 5并按照此示例生成一个数组任务。

我确定数据库至少包含1行查询。 我想我遇到了Task的问题,因为它告诉我错误信息

tasks参数包含null值。

我试过的时候:

// 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));
   }
}

我已设置断点来检查数组taskstasks[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.使用TaskTask<T>如果可用,则始终使用async / await ,即; 你正在使用.NET 4.5。

2.当您调用Task.WhenAll(tasks) ,数组中的任务可能为null。 你需要检查它并正确处理它。

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.Resultforeach循环中迭代时同步阻塞。

你的代码应该是:

var queryTasks = cg.Select(cg => db.Topics.Where(m => m.Type == type && m.Category == cg).ToListAsync());
return await Task.WhenAll(queryTasks);

请注意,EF DbContext不是线程安全的,并且不允许在其上执行并发操作。 如果是这种情况,您需要独立await每个查询。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM