Task.run() 用于多任务运行

Task.run() for multitasks runs

我想根据 return 值同时 运行 多个任务。 下面是我想要的粗略代码。

    class Program
    {
        static void tempFunc(string username,string password, ref Queue<KeyValuePair<string, string>> queue)
        {
            for(int i=0;i<10;i++)
            {
                Task.Delay(100000);
                Console.WriteLine(username + i);
            }
            queue.Enqueue(new KeyValuePair<string, string>(username, password));
        }
        static void Main(string[] args)
        {
            // A queue which is storing the username and password for different sessions and they need
            // to be passed to the method being called in Tasks.run
            Queue<KeyValuePair<string, string>> queue = new Queue<KeyValuePair<string, string>>();
            queue.Enqueue(new KeyValuePair<string, string>("user1", "password1"));
            queue.Enqueue(new KeyValuePair<string, string>("user2", "password2"));
            queue.Enqueue(new KeyValuePair<string, string>("user3", "password3"));

            while(true)
            {  // Based on the condition mentioned here(this condition is a method in real which returns a list of
               //string, which I will be passing as a parameter to the method being called in Tasks.run but I haven't put that in code here)
               if(condition)
               { 
                   if(queue.Count != 0)
                   {
                       KeyValuePair<string, string> temp = queue.Dequeue();
                       string username = temp.Key;
                       string password = temp.Value;

                       Task.Run(() => tempFunc(username, password, ref queue));
                   }
               }
            }
        }
    }

想法是有一个usernamepassword的池,当一个任务完成时,它会将使用过的usernamepassword入队,这样它就可以再次使用。可以有多个任务并且它们不相互依赖,即当一个任务是 运行ning 时,其他任务可以使用另一组 usernamepassword 和调用方法。而这一切都是 运行ning 作为 windows service 的一部分。 问题是当我使用上述代码时,它似乎是同步工作的。即等待一项任务完成,然后 运行 完成另一项任务。我究竟做错了什么?或者我使用 Tasks.run 错误的方式。

你快到了。稍作改动,您的程序将开始异步工作。

我建议的更改是:

A) 更改函数 tempFund 以包含 aysnc。并且无需包含 queue 作为此函数的参数。任务完成后,您可以在调用函数中将用户添加回队列。

public static async Task tempFunc(string username, string password)
{
    for (int i = 0; i < 10; i++)
    {
        Console.WriteLine("Before work start : {0}", username + i);
        await Task.Delay(2000);  //I have reduced it. OP can use his time
        Console.WriteLine("After work complete : {0}", username + i);
    }
}

B) 使用 ConcurrentQueue 进行线程安全操作。琼斯也提出了同样的建议。

//Use ConcurrentQueue

var queue = new ConcurrentQueue<KeyValuePair<string, string>>();

C) 将 if 块修改为:

  if (queue.Count != 0)
  {
      var temp = new KeyValuePair<string, string>();
      queue.TryDequeue(out temp);
      string username = temp.Key;
      string password = temp.Value;

      Task.Run(async () =>
      {
          Console.WriteLine("before Task start : {0}", username);
          await tempFunc(username, password);
          Console.WriteLine("after Task Ends : {0}", username);
          queue.Enqueue(new KeyValuePair<string, string>(username, password));
      });

记下其他日志,这将使 运行 中的程序异步显示。