如果TestProfile
有TestProfileAsync
版本,返回任务的代码将
class Program
{
static void Main(string[] args)
{
NewTask.Combine taskcombine = new NewTask.Combine();
ProfileClient profilesws = new ProfileClient();
var profileRecords = profilesws.GetAllProfiles();
var tasks = new List<Task<ResultClass>>();
foreach (var profile in profileRecords.ProfileRecords)
{
var testProfile = new NewTask.Profile();
testProfile.Id = profile.Id;
testProfile.Name = profile.Name;
tasks.Add(taskcombine.TestProfileAsync(testProfile))
}
int completedIndex = Task.WaitAny(tasks.ToArray());
var result = tasks[completedIndex].Result;
profilesws.Close();
taskcombine.Close();
}
}
如果函数没有一个异步的版本,你需要把它包在自己的任务。
tasks.Add(Task<ResultClass>.Factory.Start(() => taskcombine.TestProfile(testProfile)));
这都假设taskcombine.TestProfile
是线程安全的。如果它不是线程安全的,你需要更多地解释什么taskcombine.TestProfile
做,如果你能做出它的多个实例
tasks.Add(Task<ResultClass>.Factory.Start(() =>
{
NewTask.Combine taskcombine = new NewTask.Combine(); //Move the declaration inside the task so a new Combine gets created per task.
return taskcombine.TestProfile(testProfile);
}));
编辑:另外一个好办法,你可以做的是使用一个cancellation token所以如果在某些任务甚至开始之前,你已经有了一个结果,他们根本不会开始。
首先,异步版本TestProfileAsync的有签名的梦想解决方案Task<ResultClass> TestProfileAsync(NewTask.Profile a, CancllationToken token)
class Program
{
static void Main(string[] args)
{
NewTask.Combine taskcombine = new NewTask.Combine();
ProfileClient profilesws = new ProfileClient();
var profileRecords = profilesws.GetAllProfiles();
var tasks = new List<Task<ResultClass>>();
var cts = new CancellationTokenSource();
var token = cts.Token;
foreach (var profile in profileRecords.ProfileRecords)
{
var testProfile = new NewTask.Profile();
testProfile.Id = profile.Id;
testProfile.Name = profile.Name;
tasks.Add(taskcombine.TestProfileAsync(testProfile, token))
}
int completedIndex = Task.WaitAny(tasks.ToArray());
//This should stop any tasks before they even start.
cts.Cancel();
var result = tasks[completedIndex].Result;
profilesws.Close();
taskcombine.Close();
}
}
如果你没有获得一个异步的版本,这里是4.5版本的代码与任务
class Program
{
static void Main(string[] args)
{
NewTask.Combine taskcombine = new NewTask.Combine();
ProfileClient profilesws = new ProfileClient();
var profileRecords = profilesws.GetAllProfiles();
var tasks = new List<Task<ResultClass>>();
var cts = new CancellationTokenSource();
var token = cts.Token;
foreach (var profile in profileRecords.ProfileRecords)
{
var testProfile = new NewTask.Profile();
testProfile.Id = profile.Id;
testProfile.Name = profile.Name;
//If the token is canceled before the task gets to start itself it should never start and go stright to the "Canceled" state.
tasks.Add(Task.Run(() =>
{
token.ThrowIfCancellationRequested(); //In case the task started but we did get a result before the last
return taskcombine.TestProfile(testProfile); //Assumes "taskcombine.TestProfile(...)" is thread safe.
}, token));
}
var result = Task.WhenAny(tasks).Result;
//This should stop any tasks that have not spun up yet from spinning up
cts.Cancel();
profilesws.Close();
taskcombine.Close();
}
}
你真的想异步吗?或者你真的想找平行吗?因为如果它是异步的,在任务运行的同时还要完成其他工作? Taskcombine.TestProfile可以安全地从多个线程运行吗?如果你没有做任何事情,你为什么要返回结果? –
这与你的问题有何不同:http://stackoverflow.com/questions/18388419/run-console-asynchronously-to-result-a-more-efficient-output? –
我不希望它等到它经历完整的循环。我希望它运行异步,一旦结果填充关闭应用程序,而不是等待其余的。 – MohammedT