c# - 具有取消能力的长时间运行操作模式

标签 c# wpf task-parallel-library cancellation long-running-processes

为了执行长时间运行(让它在此上下文中搜索)操作,我将加载逻辑放在 TPL 任务中,因此在后台线程上调用通用方法 Search()Search() 操作可能足够长,因此我需要能够使用 CancellationToken 正确取消它。 。但是Search()操作直到完成才返回,所以我必须做一些逻辑才能实现方便且(!)快速取消。

使用 WaitHandle's 我可以实现这样的东西:

private void StartSearch() // UI thread
{
    CancellationTokenSource s = new CancellationTokenSource();
    Task.Factory.StartNew(() => StartSearchInternal(s.Token), s.Token)
}

private void StartSearchInternal(CancellationToken token) // Main Background Thread
{
    ManualResetEvent eHandle = new ManualResetEvent(false);
    Task.Factory.StartNew(() => Search(eHandle ), TaskScheduler.Default);
    WaitHandle.WaitAny(new [] { eHandle, token.WaitHandle });
    token.ThrowIfCancellationRequested();
}

private IEnumerable<object> Search(ManualResetEvent e) // Another Background thread
{
    try
    {
        // Real search call, i.e. to database, service, or AD, doesn't matter
        return RealSearch();
    }
    catch {} // Here, for simplicity of question, catch and eat all exceptions
    finally
    {
        try
        {
            e.Set();
        }
        catch {} 
    }
}

在我看来,这并不是一个优雅的解决方案。

问:还有其他方法可以完成此任务吗?

最佳答案

如果您可以控制 StartSearchInternal()Search(eHandle),那么您应该能够使用内部的 ThrowIfCancellationRequested 进行协作取消您的Search核心循环。

有关更多详细信息,我强烈建议阅读此文档:"Using Cancellation Support in .NET Framework 4" .

顺便说一句,您可能应该将对 Task.Factory.StartNew(() => StartSearchInternal(s.Token), s.Token) 返回的任务的引用存储在您的某个位置 View 模型类。您很可能想要观察其结果以及它可能引发的任何异常。您可能想查看 Lucian Wischik 的 "Async re-entrancy, and the patterns to deal with it" .

关于c# - 具有取消能力的长时间运行操作模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23539397/

相关文章:

c# - Task.WhenAny 和未观察到的异常

c# - 如何从 C# 中的 Azure HTTP 触发器函数删除 CosmosDB 中的项目

c# - WPF ClickOnce 遗漏引用

wpf - XAML 中的#region

c# - MVVM 使用工厂方法处理窗口管理

c# - 将任务异常标记为已处理

c# - 打开 XML : How to add rows and cell value after appending new sheet in existing Excel file using c#

c# - 使用 EF 查询映射 sql 查询不起作用

wpf - WPF 开发人员应该避免的常见编程错误?

c# - 以安全的方式在企业应用程序中运行多个 Task<>