RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 584930
Accepted
Alex Krass
Alex Krass
Asked:2020-10-31 18:43:56 +0000 UTC2020-10-31 18:43:56 +0000 UTC 2020-10-31 18:43:56 +0000 UTC

如何杀死长时间运行的任务?

  • 772

有一个查询最多可能需要一个小时才能完成。为了不阻塞用户界面,它通过任务。如果用户厌倦了等待,这个请求应该被取消。如何正确地做到这一点,以便连接不会在加载数据库时挂起一个小时,并且用户不会创建一堆它们?也许除了任务之外还有其他选择?

private void UpdateGrid(){
    SomeRows rows;
    Task task = new Task(() => 
    {
        rows = IDBConnectInstance.SelectRows();
    });
    task.ContinueWith(() =>
    {
        dataGridView.DataSource = rows;
    }, TaskScheduler.FromCurrentSynchronizationContext());
}

更新:

没有额外加的点,IDBConnectInstance本身就是一个来自第三方库的接口。即进入库函数IDBConnectInstance.SelectRows,停止等待完成。如果可以处理CancellationToken,问题就不会出现了。

IDBConnect
{
    SelectRows();
}

public class DBConnect: IDBConnect
{
    public List<SomeClass> SelectRows()
    {
        String query = "Очень долгий SELECT из БД";
        List<SomeClass> result = new List<SomeClass>();
        using(OracleConnection dbconn = new OracleConnection(ConnectionString))
        {
            dbconn.Open();

            OracleCommand command = new OracleCommand(query, dbconn);
            OracleDataReader reader = command.ExecuteReader();
            while (reader.Read())
            {
                SomeClass someClass = new someClass()
                {
                    SomeField = reader[0],
                    SomeField = reader[1],
                    ...
                }
                result.Add(someClass);
            }
            reader.Close();
            dbconn.Close();
        }
        return result;
    }
}

到目前为止,只有一个想法返回Thread并使用已弃用的Thread.Abort();

c#
  • 3 3 个回答
  • 10 Views

3 个回答

  • Voted
  1. eastwing
    2020-10-31T20:57:43Z2020-10-31T20:57:43Z

    引用MSDN:

    如果父任务在子任务或嵌套任务启动后自行取消,则嵌套(子)任务将终止,除非它有自己的取消逻辑。

    因此,您可以尝试这样的拐杖:启动带有计时器的父任务,从中启动您的孩子。tayier过期后,取消parent,理论上会导致child的取消(如果它没有自己的取消逻辑©)

    • 1
  2. Alexander Alexeev
    2020-10-31T21:23:09Z2020-10-31T21:23:09Z

    典型方法——两项任务。如果您需要“杀死”而不会失败,那么显式启动一个单独的线程并对其调用 Thread.Abort 是有意义的。

    • 1
  3. Best Answer
    Евгений
    2020-11-03T06:48:41Z2020-11-03T06:48:41Z

    最好让用户能够根据命令取消。

    private CancellationTokenSource _tokenSource;
    private bool _isWorked = false;
    
    private void CancelUpdateGrid()
    {
        _tokenSource.Cancel();
    }
    
    private void UpdateGrid()
    {
        if (_isWorked)
        {
           return;
        }
    
        _isWorked = true;
    
        SomeRows rows;
    
        // создаём CancellationTokenSource который отменит операцию
        _tokenSource = new CancellationTokenSource();
    
        // В задачу передадим нужный нам токен.
        Task task = Task.Run(() => 
        {
             var t = Thread.CurrentThread;
            using (cancellationSource.Token.Register(t.Abort))
            {
                rows = IDBConnectInstance.SelectRows();
            }
        }, _tokenSource.Token).ContinueWith(t =>
        {
            dataGridView.DataSource = rows;
            _isWorked = false;
        });
    }
    

    我提供的代码针对取消的概念进行了简化。

    • 1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何停止编写糟糕的代码?

    • 3 个回答
  • Marko Smith

    onCreateView 方法重构

    • 1 个回答
  • Marko Smith

    通用还是非通用

    • 2 个回答
  • Marko Smith

    如何访问 jQuery 中的列

    • 1 个回答
  • Marko Smith

    *.tga 文件的组重命名(3620 个)

    • 1 个回答
  • Marko Smith

    内存分配列表C#

    • 1 个回答
  • Marko Smith

    常规赛适度贪婪

    • 1 个回答
  • Marko Smith

    如何制作自己的自动完成/自动更正?

    • 1 个回答
  • Marko Smith

    选择斐波那契数列

    • 2 个回答
  • Marko Smith

    所有 API 版本中的通用权限代码

    • 2 个回答
  • Martin Hope
    jfs *(星号)和 ** 双星号在 Python 中是什么意思? 2020-11-23 05:07:40 +0000 UTC
  • Martin Hope
    hwak 哪个孩子调用了父母的静态方法?还是不可能完成的任务? 2020-11-18 16:30:55 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    Arch ArrayList 与 LinkedList 的区别? 2020-09-20 02:42:49 +0000 UTC
  • Martin Hope
    iluxa1810 哪个更正确使用:if () 或 try-catch? 2020-08-23 18:56:13 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5