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));
}
}
}
}
}
想法是有一个username
和password
的池,当一个任务完成时,它会将使用过的username
和password
入队,这样它就可以再次使用。可以有多个任务并且它们不相互依赖,即当一个任务是 运行ning 时,其他任务可以使用另一组 username
和 password
和调用方法。而这一切都是 运行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));
});
记下其他日志,这将使 运行 中的程序异步显示。
我想根据 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));
}
}
}
}
}
想法是有一个username
和password
的池,当一个任务完成时,它会将使用过的username
和password
入队,这样它就可以再次使用。可以有多个任务并且它们不相互依赖,即当一个任务是 运行ning 时,其他任务可以使用另一组 username
和 password
和调用方法。而这一切都是 运行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));
});
记下其他日志,这将使 运行 中的程序异步显示。