如何执行任务列表?

时间:2016-08-16 17:36:03

标签: c# asp.net-mvc task

我有一个List<System.Security.Claim>列表,我希望异步添加每个声明。我很好奇如何运行所有任务并设置boolean以便稍后使用以确保所有任务都已运行。

foreach (var claim in claims)
{
    claimTasks.Add(UserManager.AddClaimAsync(user.Id, claim));   
}

claimResultSucceeded = Task.WhenAll(claimTasks).IsCompleted;

我也试过这个:

foreach (var claim in claims)
{
    claimTasks.Add(Task.Run(() => UserManager.AddClaimAsync(user.Id, claim)));   
}

claimResultSucceeded = Task.WhenAll(claimTasks).IsCompleted;

编辑:正如您在下面的照片中看到的那样,任务正处于故障状态:

  

{“第二次操作在此前一个上下文之前开始   异步       操作完成。使用'await'确保任何异步操作       在此上下文中调用另一个方法之前已完成。任何实例       成员不保证是线程安全的。“}

enter image description here

2 个答案:

答案 0 :(得分:1)

你确定吗? Task.WhenAll将接受一组Task(并接受这些任务的任何返回值)并返回一个你可能要等待完成的新任务,就像你建议的那样?

我已将以下代码示例放在一起,这基本上就是您所展示的内容(带有一些无意义的数据以确保有足够的编译) -

static async void Main(string[] args)
{
    // Declare some references to work with (this data is rubbish, it's just here so
    // that everything compiles)
    var userManager = new UserManager<User, Key>(null);
    var user = new User();
    var claims = new List<Claim>();
    var claimTasks = new List<Task<IdentityResult>>();

    // This is basically the code that appears in the question - it compiles fine
    foreach (var claim in claims)
    {
        claimTasks.Add(userManager.AddClaimAsync(user.Id, claim));
    }

    // WhenAll returns a single task that will be completed when all of the individual
    // claims tasks have completed
    var claimResults = await Task.WhenAll(claimTasks);

    // When this happens, you should be able to look at each of the IdentityResults
    // instances in the claimResults array to ensure they all succeeded
    // Note: I'm presuming a little here since I'm not too familiar with these types, but
    // it seems reasonable that the Succeeded flag on each IdentityResult should indicate
    // whether or not it was successfully retrieved
    var allRequestsSucceeded = claimResults.All(c => c.Succeeded);
}

// This struct and class have no purpose other than making the code compile
public struct Key : IEquatable<Key>
{
    public bool Equals(Key other) { throw new NotImplementedException(); }
}

public class User : IUser<Key>
{
    public Key Id
    {
        get { throw new NotImplementedException(); }
    }

    public string UserName
    {
        get {  throw new NotImplementedException(); }
        set { throw new NotImplementedException(); }
    }
}

答案 1 :(得分:1)

您的新错误来自实体框架。每个db上下文实例只能有一个异步操作。就这样做:

foreach (var claim in claims)
{
    var result = await UserManager.AddClaimAsync(user.Id, claim);
    if (result.Succeded == false) {
        // Handle the error
    }
}

编辑: 合并@Dan Roberts建议。