c# - 是否可以将 CancellationToken 与 ExecuteReader 一起使用?

标签 c# .net

新的异步 ExecuteReaderAsync 采用 CancellationToken。有没有办法取消旧的同步ExecuteReader

在我们的例子中,所有数据操作在后台线程上都是同步的,所以 await 不是一个选项。我不想启动第二个线程 - Task.Run(() => command.ExecuteReaderAsync(token)).Result 似乎只是为了能够从 UI 线程取消而浪费。

最佳答案

性能测试表明,与使用 Begin 或 Async API 及其线程池延续相比,使用专用同步数据读取线程的性能优势几乎提高了 2 倍。 (由于数千万行将在几秒钟内加载,因此在这种情况下我们更喜欢性能。)

方便 token 传递的扩展方法:

public static SqlDataReader ExecuteReader(this SqlCommand command, CommandBehavior commandBehavior, CancellationToken cancellationToken)
{
    try
    {
        using (cancellationToken.Register(command.Cancel))
            return command.ExecuteReader(commandBehavior);
    }
    catch (SqlException) when (cancellationToken.IsCancellationRequested)
    {
        throw new OperationCanceledException(cancellationToken);
    }
}

我用 Reflector 反编译做了一些探索。 Begin 和 Async 版本都非常节俭,但都完全基于 TPL 异步。因此,两者都有用于延续的线程池调度。

此扩展方法没有线程开销。在 token 源上调用 Cancel 的线程也会调用 command.Cancel,这将立即在数据线程中导致 SqlException

关于c# - 是否可以将 CancellationToken 与 ExecuteReader 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23685751/

相关文章:

c# - 将 Drawing.Color 转换为 HTML 颜色值

c# - RegistryKey 上次写入时间

c# - 带有 WHERE 子句的 2 个表的 MySql 内部连接

c# - 在文本框中拖动文件或文件夹? C#

c# - 从 IQueryable<ICollection> LINQ 查询中获取 ICollection

c# - 使用 stackalloc 分配的内存的初始化

c# - 使用linq to xml遍历xml树中的每个元素

.net - 将 .Net Framework 2.0 升级到 4.5

c# - 如何在Ubuntu上托管/发布.Net Core Web API?

c# - 设计 : Queue Management question (C#)