【问题标题】:C# Restarting a thread with a different parameterC# 使用不同的参数重新启动线程
【发布时间】:2018-04-30 21:26:49
【问题描述】:

我想在某个用户事件上启动一个后台线程,如果变量在传入和检查之间发生变化,我会等待/睡眠 10 秒以执行某些操作。但是,在那 10 秒内,相同的用户事件可以重复,我想中断并重置线程以使用新变量并在 10 秒后重新开始。 例如,

private static int index = 0;
private static Thread myThread = null;

if(myThread != null && myThread.IsAlive) {
         // need to 'restart' the thread with updated index
         /* Suspend? Resume? */
    } else {
         // create a new thread and start countdown
         myThread = new Thread(new ThreadStart( some_Thread(index) ));
         myThread.Start();
    }

我读到suspend() 和resume() 已经过时了,而且我已经阅读了一些关于Auto/ManualResetEvent 的帖子,但它们并不是我想要的。它可能更接近 Abort() 然后 Start() 一个新的,但显然这是不明智的。

那么有什么建议可以用一个静态线程句柄来实现吗?同样,10 秒的“睡眠”必须是可中断的,此后,线程可以被丢弃或重新启动。谢谢!

【问题讨论】:

    标签: c# multithreading


    【解决方案1】:

    我想在一些用户事件上启动一个后台线程,

    您正在做我们所谓的“XY problem”。您对如何解决问题有一个完全错误的想法,并且您正在询问有关如何使这种错误方式起作用的问题。相反,请专注于您真正遇到的以用户为中心的问题并提出相关问题。

    如果变量在传入的时间和检查的时间之间发生变化,我会等待/睡眠 10 秒来做某事。

    不要做任何这些事情。如果你正在创建一个线程,它的工作就是睡觉,那么你做的事情很有可能是非常非常错误的。线程很昂贵;仅当您要调度 CPU 为该线程提供服务时才创建一个线程。

    当您考虑创建线程时,问问自己“我会雇用一名工人来完成这项任务吗?”十秒的计算机时间是百亿纳秒;这就像雇用一个工人并付钱让他们睡几个世纪。你永远不会那样做;您只需将“稍后再做”放在待办事项列表中,稍后再返回。如果它被取消,你会从你的待办事项列表中删除它。

    您想要做的是零额外线程。 创建一个可取消的异步工作流,awaits 和 Task.Delay 在完成必须在十秒后完成的工作之前。 如果用户事件在延迟期间发生,则取消工作流并开始新的工作流.

    如果延迟之后的工作是 CPU 密集型的,然后安排一个工作线程并等待结果。如果不是——如果是 CPU 工作在 30 毫秒或更短的时间内返回——那么只需在主线程上运行工作。如果是 IO 门控,那么使用异步版本的 IO API 留在主线程上。您希望尽可能少地制作线程。

    小心。即使一切都在一个线程上,但在这样的可取消工作流程中仍然可能存在竞争条件。您仍然需要考虑异步工作流的非依赖部分的所有可能交错。

    【讨论】:

    • 我实际上正在编写一个键盘记录器(用于一个类,不是恶意的),当用户按下一个键并试图弄清楚如何将缓冲区刷新到远程时,全局钩子会被调用服务器在用户没有按任何键但尚未填充缓冲区的空闲时间之后。除了可以保证在延迟后执行而不需要再次调用钩子的线程之外,我想不出其他任何东西。 Main() 线程在“Application.Run()”之后挂起。我不知道存在这种异步工作流程之类的东西,所以谢谢!这看起来很适合我的需要。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-26
    相关资源
    最近更新 更多