简体   繁体   English

使用不同的数据多次调用相同的异步任务c#

[英]make multiple calls to same async tasks with different data c#

I have a list which contains some documents (for simplicity strings). 我有一个包含一些文档的列表(用于简单字符串)。 Now the list is getting populated slowly. 现在列表正在慢慢填充。 What I want to do is when the size of the list reaches 20 I want to call another function that will print these strings asynchronously without stopping the main method. 我想做的是当列表的大小达到20时,我想调用另一个函数,该函数将异步打印这些字符串而不停止main方法。 After lot of searching I have managed to put together this code 经过大量搜索,我设法将这段代码放在一起

public void DoStuff()
{
    Class1 p = new Class1();
    List<string> list = new List<string> { };
    var TList = new List<Task>();
    int i = 0;
    while (i < 90)
    {
        list.Add(i.ToString());
        if (list.Count == 20)
        {
            Console.WriteLine("List contents when calling: " + list[0]);
            TList.Add(Task.Run(() => publishDoc(list)));
            list.Clear();
        }
        i++;
    }
    if (list.Count != 0)
    {
        TList.Add(Task.Run(() => publishDoc(list)));
    }
    Task.WhenAll(TList).Wait();
    Console.WriteLine("Done DoStuff");
}

public async Task publishDoc(List<string> docs)
{
    Console.WriteLine(iter++ + " " + docs[0]);
    await Task.Run(() => Thread.Sleep(1000));
    foreach (var val in docs)
    {
        Console.Write(val + " ");
    }
    Console.WriteLine();
}

This is what I am getting as output 这就是我得到的输出

List contents when calling: 0
List contents when calling: 20
List contents when calling: 40
List contents when calling: 60
1 80
3 80
0 80
2 80
4 80
80 80 80 80 81 82 83 84 85 86 87 88 89
81 82 83 84 85 86 87 88 89
81 82 83 84 85 86 87 88 89
81 82 83 84 85 86 87 88 89
80 81 82 83 84 85 86 87 88 89
Done DoStuff
Done Main

I can't figure out why it is only printing the last passed data ie why the passed list is getting overwritten. 我不知道为什么它只打印最后传递的数据,即为什么传递的列表被覆盖。 Now if I do this 现在如果我这样做

public void DoStuff()
{
    Program2 p = new Program2();
    List<string> list = new List<string> { };
    int i = 0;
    while (i < 90)
    {
        list.Add(i.ToString());
        if (list.Count == 20)
        {
            Console.WriteLine("List contents when calling: " + list[0]);
            var tasks = publishDoc(list);
            if (tasks.Result == "Done")
            {
                Console.WriteLine("Done " + list[0]);
            }
            list.Clear();
        }
        i++;
    }
    if (list.Count != 0)
    {
        var tasks = publishDoc(list);
        if (tasks.Result == "Done")
        {
            Console.WriteLine("Done " + list[0]);
        }
    }
    Console.WriteLine("Done DoStuff");
}

public async Task<string> publishDoc(List<string> docs)
{
    Console.WriteLine(iter++ + " " + docs[0]);
    foreach (var val in docs)
    {
        Console.Write(val + " ");
    }
    Console.WriteLine();
    return await Task.Run(() => "Done");
}

I get this output 我得到这个输出

List contents when calling: 0
0 0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Done 0
List contents when calling: 20
1 20
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
Done 20
List contents when calling: 40
2 40
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
Done 40
List contents when calling: 60
3 60
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
Done 60
4 80
80 81 82 83 84 85 86 87 88 89
Done 80
Done DoStuff
Done Main

This is giving the correct output but is doing it synchronously which I don't want. 这给出了正确的输出,但是却同步地执行了我不想要的输出。 Please help and thanks in advance. 请帮助并提前致谢。

you have to do like this , as in loop it points to same instance of list every time that might causing issue , so I suggest you create copy of list before passing it to function publishDoc 您必须这样做,因为在循环中它每次都指向列表的同一实例,这可能会导致问题,因此我建议您在将列表传递给publishDoc函数之前先创建列表的副本

while (i < 90)
    {
        list.Add(i.ToString());
        if (list.Count == 20)
        {
            List<string> copy = list.ToList();
            Console.WriteLine("List contents when calling: " + copy[0]);
            TList.Add(Task.Run(() => publishDoc(copy)));
            list.Clear();
        }
        i++;
    }

Refer this answer also : Starting Tasks In foreach Loop Uses Value of Last Item 另请参阅此答案: 在foreach循环中启动任务使用最后一项的值

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

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