c# - 使用 C++/CLI 的任务并行库 Task.ContinueWith

标签 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.ContinueWith(...) 定义任务的顺序,如 Task chaining (wait for the previous task to completed) 中所述。我想做的是(在 C# 中):

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

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

这有可能吗?

最佳答案

虽然 C++ 不支持托管 lambda,但您可以做一些小改动来让委托(delegate)工作,并在必要时覆盖您自己的变量。在本例中,ContinueWith 委托(delegate)将 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>^ versionCheckTask)
{
    if(versionCheckTask->Result) QueryUserToDownloadNewVersion();
}

关于c# - 使用 C++/CLI 的任务并行库 Task.ContinueWith,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26884905/

相关文章:

java - 如何在 Spring 中的 REST 服务的 HandlerInterceptor 中填充 ModelAndView

c# - 在接口(interface)级别强制执行 getter setter 访问

c# - 如何使用异步调用 WCF 关闭客户端代理

c# - 如果每个 async 都有一个 await,并且每个 await 都应用于一个 async,那么它在哪里以及如何结束?

c# - 合格双倍显示不正常

java - 这个单例对序列化和反射攻击都有抵抗力吗?

c# - 为什么 Windows Phone 7 不完全支持 C# 规范?

c# - IAuthenticationManager.Challenge 不调用 ExternalLoginCallback

java - 从文件中获取一个重复的字段而不需要加载整个文件

Java volatile 和副作用