任务并行库Task.ContinueWith使用C ++ / CLI

时间:2014-11-12 10:38:38

标签: c# .net concurrency c++-cli task-parallel-library

我已经开始在我的C ++ / CLI项目中使用任务并行库(TPL)。这在运行可以独立运行的简单任务时运行良好。我写的软件能够检查服务器上的更新。这是先前在主线程上完成的,但是这使得GUI在检查期间冻结,这实际上没有给用户提供软件的良好印象。

因此我测试了使用TPL来运行检查。我可以开始检查更新(按照Using .NET (3.5) Task Parallel Library in C++/ CLI的指示),如下所示:

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具有很好的功能,可以使用Task chaining (wait for the previous task to completed)中概述的Task.ContinueWith(...)来定义任务的顺序。我想做的是(在C#中):

Task.Factory.StartNew( () => IsUpdateAvailable())
   .ContinueWith(() => OnVersionCheckDone(antecendent.Result), 
       TaskScheduler.FromCurrentSynchronizationContext());

如果确实有新版本可用,OnVersionCheckDone(bool)可以负责询问用户如何继续。有关如何执行此操作的所有示例都是用C#编写的,我无法将其转换为C ++ / CLI。

这一切都可能吗?

1 个答案:

答案 0 :(得分:0)

尽管C ++不支持托管的lambda,但是您可以做些小事以使委托开始工作,并在必要时覆盖您自己的变量。在这种情况下,ContinueWith委托将Task作为参数,因此我们不必做太多事情。

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>^ t)
{
    if(t->Result) QueryUserToDownloadNewVersion();
}