任务<t>。等待永不返回

时间:2016-05-20 10:35:19

标签: c# task

我遇到了一个问题,我已经归结为此代码段:

var task=new Task<int>(()=>5);

task.Wait();

问题是task.Wait()永远不会返回。我过去编写的代码工作正常。

到目前为止我已尝试过:

  • 将整个事物包装在异步函数中并在其上调用Wait(相同的行为)
  • 这最初是一个包含在WaitAll中的承诺列表,并在停滞不前的情况下调用Wait
  • 尝试调用Task.Start,但收到了一个例外情况,声明Task.Start没有使用承诺风格的任务

那么,有什么想法吗?

修改

导致此问题的完整代码段:

static void EfTest()
{
    _start = DateTime.Now;
    var task = CreateEfTask();

    var efTasks= Enumerable.Range(0, 1).Select(i => CreateEfTask()).ToList();

    var t= Task.WhenAll(efTasks);
    t.Wait();

    var results = t.Result;
}

private static Task<Result> CreateEfTask()
{
    return new Task<List<PricingRule>>(
        () => new global::Entities
            .Entities()
            .PricingRules
            .Where(pr => pr.IsEnabled).ToList())
            .ContinueWith(t => new Result 
            {
                PricingRules = t.Result,
                TimeSpan = DateTime.Now.Subtract(_start)
            });
}

Task.Start之前放置t.Wait会发出错误消息,指出您无法在promise stile任务中使用start。

3 个答案:

答案 0 :(得分:2)

你应用中某处出现了其他问题

using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var task = new Task<int>(() => 5);
            task.Start();
            task.Wait();
        }
    }
}

每次都运行完成,没有错误。

答案 1 :(得分:2)

来自Task.Wait的任务永远不会结束,因为它正在等待的任务永远不会开始。你需要启动它们,例如

var efTasks= Enumerable.Range(0, 1).Select(i => CreateEfTask()).ToList();

foreach(var t in eTasks) {
    t.Start();
}

var t= Task.WhenAll(efTasks);
t.Wait();

虽然你可能想在CreateEfTask()中启动它:

private static Task<List<PricingRule>> CreateEfTask()
{
    var t = new Task<List<PricingRule>>(
        () => new global::Entities.Entities().PricingRules.Where(pr => pr.IsEnabled).ToList()).ContinueWith(t=>new Result {PricingRules = t.Result,TimeSpan = DateTime.Now.Subtract(_start)});
    t.Start();
    return t;
}

如果这是实体框架,您应该能够异步执行查询而无需构建自己的任务并启动它们,例如。

private static Task<List<PricingRule>> CreateEfTask() {
    return new global::Entities.Entities().PricingRules.Where(pr => pr.IsEnabled).ToListAsync();
}

答案 2 :(得分:0)

您的代码没有启动任务。在等待之前,您需要在任务上调用Start()

您还可以使用Task.Factory.StartNew方法,该方法在功能上等同于使用构造函数创建任务然后启动它,例如:

var task = Task.Factory.StartNew(() => 5);

task.Wait()