如果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