任务并行库了WaitAny与特定的结果 [英] Task Parallel Library WaitAny with specified result
问题描述
我试着写一些code,这将使Web服务调用了一些并行不同的服务器,因此TPL似乎是显而易见的选择使用。
只有我的Web服务调用一会再回到我想要的结果,所有的人则不会。我试图找出有效有一个 Task.WaitAny
,但只有疏通当第一个工作
的一种方式符合条件的回报。
我试着用了WaitAny
,但不能工作了放在哪里过滤器。我得到了这个远:
公共无效SearchServers()
{
VAR服务器=新[] {服务器1,服务器2,服务器3,服务器4};
VAR任务=服务器
。选择(S = GT;任务<布尔> .Factory.StartNew(服务器=> CallServer((字符串)服务器),S))
.ToArray(); Task.WaitAny(任务); //我怎么说了WaitAny,其中结果为真? //省略:取消所有未完成的任务,因为正确的服务器已被发现
}私人布尔CallServer(字符串服务器)
{
// ...拨打电话到服务器并返回结果...
}
修改:快速澄清,以防万一有上述任何混淆。我试图做到以下几点:
- 对于每一台服务器,启动
工作
来检查 - 不管,等到服务器返回true(只有1个服务器的最大永远不会返回true)
- 或者,等到所有的服务器都返回false,即存在不匹配。
最好的是我能想到的是指定一个 ContinueWith
每个任务
,检查结果,如果真正
取消其他任务。对于取消的任务,你可能要使用的CancellationToken 。
VAR任务=服务器
。选择(S = GT; Task.Run(...)
.ContinueWith(T =>
如果(t.Result){
//取消其他线程
}
)
).ToArray();
更新:另一种解决办法是将了WaitAny
,直至正确的任务完成(但它也有一些缺点,例如,从列表中删除完成的任务,并创建一个新的数组出其余的是相当沉重的操作):
列表<任务<布尔>>任务= servers.Select(S =>任务&下;布尔> .Factory.StartNew(服务器= GT; CallServer((字符串)服务器)中,s))了ToList();布尔结果;
做{
INT IDX = Task.WaitAny(tasks.ToArray());
结果=任务[IDX]。结果;
tasks.RemoveAt(IDX);
}而(导致&安培;!&安培; tasks.Count大于0);//取消其他任务
I'm trying to write some code that will make a web service call to a number of different servers in parallel, so TPL seems like the obvious choice to use.
Only one of my web service calls will ever return the result I want and all the others won't. I'm trying to work out a way of effectively having a Task.WaitAny
but only unblocking when the first Task
that matches a condition returns.
I tried with WaitAny
but couldn't work out where to put the filter. I got this far:
public void SearchServers()
{
var servers = new[] {"server1", "server2", "server3", "server4"};
var tasks = servers
.Select(s => Task<bool>.Factory.StartNew(server => CallServer((string)server), s))
.ToArray();
Task.WaitAny(tasks); //how do I say "WaitAny where the result is true"?
//Omitted: cancel any outstanding tasks since the correct server has been found
}
private bool CallServer(string server)
{
//... make the call to the server and return the result ...
}
Edit: Quick clarification just in case there's any confusion above. I'm trying to do the following:
- For each server, start a
Task
to check it - Either, wait until a server returns true (only a max of 1 server will ever return true)
- Or, wait until all servers have returned false, i.e. there was no match.
The best of what I can think of is specifying a ContinueWith
for each Task
, checking the result, and if true
cancelling the other tasks. For cancelling tasks you may want to use CancellationToken.
var tasks = servers
.Select(s => Task.Run(...)
.ContinueWith(t =>
if (t.Result) {
// cancel other threads
}
)
).ToArray();
UPDATE: An alternative solution would be to WaitAny
until the right task completed (but it has some drawbacks, e.g. removing the finished tasks from the list and creating a new array out of the remaining ones is quite a heavy operation):
List<Task<bool>> tasks = servers.Select(s => Task<bool>.Factory.StartNew(server => CallServer((string)server), s)).ToList();
bool result;
do {
int idx = Task.WaitAny(tasks.ToArray());
result = tasks[idx].Result;
tasks.RemoveAt(idx);
} while (!result && tasks.Count > 0);
// cancel other tasks
这篇关于任务并行库了WaitAny与特定的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!