Reputation: 131
I have started using Task Parallel Library (TPL) in my C++/CLI project. This works well when running simple tasks which can be run independently. The software that I'm writing has the ability to check for updates on a server. This was previously done on the main thread of the but this made the GUI freeze for the duration of the check which really doesn't give a good impression of the software for the user.
I have therefore tested with using TPL to run the check. I can start the check for updates (following the directions from Using .NET (3.5) Task Parallel Library in C++/ CLI) like this:
Void SoftwareUpdateChecker::RunCheck(Boolean automatic)
{
Task<Boolean>^ versionCheckTask = Task<Boolean>::Factory->StartNew( gcnew Func<Boolean>(this, &SoftwareUpdateChecker::IsUpdateAvailable) );
// This line is the problem, this freezes the main thread...
versionCheckTask->Wait();
Boolean isNewerVersionOnServer = versionCheckTask->Result;
if(isNewerVersionOnServer)
{
QueryUserToDownloadNewVersion();
}
}
TPL has the nice feature of making it possible to define the order of tasks using Task.ContinueWith(...) as outlined in Task chaining (wait for the previous task to completed). What I want to do is (in C#):
Task.Factory.StartNew( () => IsUpdateAvailable())
.ContinueWith(() => OnVersionCheckDone(antecendent.Result),
TaskScheduler.FromCurrentSynchronizationContext());
Where OnVersionCheckDone(bool) can take care of asking the user how to proceed if there is indeed a new version available. All examples for how to do this are written in C# and I have not been able to convert this into C++/CLI.
Is this at all possible ?
Upvotes: 2
Views: 2517
Reputation: 4894
While C++ does not support managed lambdas, you can do a little fanagling to get delegates to work, and cover your own variables when necessary. In this case, the ContinueWith delegate takes a Task as an argument, so we don't have to do too much.
Void SoftwareUpdateChecker::RunCheck(Boolean automatic)
{
Task<Boolean>^ versionCheckTask = Task<Boolean>::Factory->StartNew( gcnew Func<Boolean>(this, &SoftwareUpdateChecker::IsUpdateAvailable) );
versionCheckTask->ContinueWith(gcnew Action<Task<Boolean>^>(this, &SoftwareUpdateChecker::OnVersionCheckDone), TaskScheduler::FromCurrentSynchronizationContext());
}
Void SoftwareUpdateChecker::OnVersionCheckDone(Task<Boolean>^ versionCheckTask)
{
if(versionCheckTask->Result) QueryUserToDownloadNewVersion();
}
Upvotes: 2