[英]Right way of using TPL for this specific constellation ( Continuous parallel Tasks )
我希望我能在这里得到一些帮助,尝试了各种可行的方法,但始终会遇到一些问题。 使用以下示例代码将是最好的方法:
任务A + B + C应该并行运行,但是任务B应该比任务A稍有延迟地开始。根据单个任务devsearch / conssearch的结果,它们应该自行重启或启动任务“ GO”。 GO将仅运行一次,并将重新启动调用任务。
如前所述,什么是最好的方法。 Parallel.Invoke在这里合适吗? 我应该切换到“任务”并将其移到“主要部分”吗?
我非常感谢您的帮助。 提前致谢。 请不要在意任务或细节中的小错误,仅以构建此示例为例,不要太复杂。
更新/其他信息:
我有一个Windows窗体应用程序。 逻辑如下:
我有3个任务
对于conssearch和devsearch的任务,我给出了谁是发送者,布尔,帐户和数组的参数。 在任务中,我执行等待的异步HTTP请求。 对数组中的每个项目都完成了此请求。 对于http请求,我需要登录数据,这是通过帐户传递的。 我可以多次登录(Cookiehandling等已完成并正在工作),这就是为什么我想同时并行运行conssearch的原因。 需要并行执行conssearch之间的延迟,因为我不想获得相同的结果。 我每个帐户都有一个rps限制,这就是为什么我在单个任务中都有await.delay的原因。
因此,总之,我想在按下“开始”按钮时启动并行conssearch x 2和devsearch。
现在,每个任务都应彼此独立运行。
我希望现在可以更好地理解我要做什么。
public async void button1_Click(object sender, EventArgs e)
{
while (true)
{
Parallel.Invoke(
() => {
Task taskA = Task.Factory.StartNew(() => conssearch("cons", false, Account1, devArr));
System.Threading.Thread.Sleep(335);
Task taskB = Task.Factory.StartNew(() => conssearch("cons", false, Account2, devArr));
taskA.Wait();
taskB.Wait();
},
() => Task.Run(() => devsearch("dev", false, Account3, devArr)),
);
}
}
private async Task conssearch(object sender, bool GO, string acc, Array[] devArr)
{
for (int i = 0; i < devArr.Length; i++)
{
// Do some HTTP here....
If ....
GO = True;
}
await Task.Delay(100);
if (GO)
{
listView1.BeginInvoke(new MethodInvoker(() => listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent)));
listView2.BeginInvoke(new MethodInvoker(() => listView2.Items.Clear()));
GO("cons", acc, devArr);
}
else
{
//conssearch("cons", false, acc, devArr)
}
}
private async Task devsearch(object sender, bool GO, string acc, Array[] devArr)
{
for (int i = 0; i < devArr.Length; i++)
{
// Do some HTTP here....
If ....
GO = True;
}
await Task.Delay(100);
if (GO)
{
listView1.BeginInvoke(new MethodInvoker(() => listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent)));
listView2.BeginInvoke(new MethodInvoker(() => listView2.Items.Clear()));
GO("cons", acc, devArr);
}
else
{
//devsearch("dev", false, acc, devArr)
}
}
private async Task GO(object sender, string acc, Array[] devArr)
{
{
// Do some HTTP here....
}
await Task.Delay(100);
if (sender == "tra")
await conssearch(sender, false, client, devArr);
else
await devsearch(sender, false, client, devArr);
}
我将只专注于运行这三个任务,仅此而已。
首先,开始一个任务,等待固定的时间,然后开始第二个任务,这听起来很可疑。 延迟的目的是什么? 我想不出最能代表这种方式的东西。
现在,将Parallel
和Task
结合起来通常没有多大意义。 如果Parallel
方法之一适合您,请使用该方法,而不要使用Task
。 如果您需要更复杂的东西,请使用Task
。
在您的情况下,由于可以使用await
,因此我将利用这一优势:有一个async
方法可以延迟启动conssearch
Task
。 然后,在另一个方法中,调用该方法,启动devsearch
Task
然后等待两者均完成。 就像是:
async Task RunConsSearches()
{
var taskA = Task.Run(() => ConsSearch("cons", false, Account1, devArr));
await Task.Delay(335);
var taskB = Task.Run(() => ConsSearch("cons", false, Account2, devArr));
await Task.WhenAll(taskA, taskB);
}
…
var consSeachTask = RunConsSearches();
var devSearchTask = Task.Run(() => DevSearch("dev", false, Account3, devArr));
await Task.WhenAll(consSeachTask, devSearchTask);
更好的方法是将ConsSearch
和DevSearch
转换为适当的async
,但是很难说这将有多困难。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.