C# 任务并行库任务。使用C++/CLI

C# 任务并行库任务。使用C++/CLI,c#,.net,concurrency,c++-cli,task-parallel-library,C#,.net,Concurrency,C++ Cli,Task Parallel Library,我已经开始在我的C++/CLI项目中使用任务并行库(TPL)。这在运行可以独立运行的简单任务时效果很好。我正在编写的软件能够检查服务器上的更新。这之前是在的主线程上完成的,但这使得GUI在检查期间冻结,这实际上不会给用户留下软件的良好印象 因此,我测试了使用TPL来运行检查。我可以像这样开始检查更新(按照中的说明): Void SoftwareUpdateChecker::RunCheck(Boolean automatic) { Task<Boolean>^ version

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

因此,我测试了使用TPL来运行检查。我可以像这样开始检查更新(按照中的说明):

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();
    }
}
其中OnVersionCheckDone(bool)可以询问用户如果确实有新版本可用,如何继续。所有关于如何做到这一点的示例都是用C#编写的,我还无法将其转换为C++/CLI


这有可能吗

> C++不支持托管lambDas,您可以做一些小技巧以使委托工作,并在必要时覆盖自己的变量。在这种情况下,ContinueWith委托将任务作为参数,因此我们不必做太多

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();
}
Void SoftwareUpdateChecker::运行检查(布尔自动)
{
Task^versionCheckTask=Task::Factory->StartNew(gcnew Func(this,&SoftwareUpdateChecker::IsUpdateAvailable));
versionCheckTask->ContinueWith(gcnew操作(此操作和&SoftwareUpdateChecker::OnVersionCheckOne)、TaskScheduler::FromCurrentSynchronizationContext());
}
Void SoftwareUpdateChecker::OnVersionCheckOne(任务^versionCheckTask)
{
if(versionCheckTask->Result)QueryUserToDownloadNewVersion();
}

启动任务并等待它是毫无意义的,您不妨在同一线程上运行代码。如果您想使用Task,C++/CLI不支持lambdas是非常痛苦的,但是您必须处理它。您将获得许多小型私人助手函数。永远不要忽视用C#编写这段代码的选项,语言互操作是一个强大的.NET功能。我同意,仅仅等待任务是没有意义的。我所寻找的是一种解决lambdas缺少支持的方法。值得一提的是,从Hans的评论中,我惊讶地发现C++/CLI不支持托管lambdas。在做一些研究以了解更多关于为什么会这样、未来可能会怎样以及替代方案是什么的过程中,我发现有几页特别有用(包括四年前Hans的一个答案):以及
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();
}