【问题标题】:running threads in c# .net在 c# .net 中运行线程
【发布时间】:2012-12-23 03:32:07
【问题描述】:

让我们考虑一个经常改变字符串包含值的方法。 我需要创建每 1 分钟运行一次以从字符串中获取值的线程。

有可能吗?

我尝试了以下代码,它使除特定线程之外的整个进程休眠:

System.Threading.Thread.Sleep(10000);

【问题讨论】:

    标签: c# .net multithreading


    【解决方案1】:

    用途:

    new Thread(delegate()
        {
             while(true)
             {
                 // Do stuff
                 Thread.sleep(60000);
             }
        }).Start();
    

    60000 毫秒是一分钟

    Thread.sleep 使当前线程进入睡眠状态

    【讨论】:

    • 当 OP 明确表示由于在 UI 线程上休眠而阻塞整个进程时,不确定休眠 60 秒比休眠 10 秒好多少?
    • @AlexeiLevenkov 他不应该在主线程 ofc 上调用 sleep,而是在后台线程中调用。
    【解决方案2】:

    如果您想在定义的时间段内运行线程进程,System.Threading.Timer 类将是完美的

    var timer = new System.Threading.Timer((o) =>
    {
        // do stuff every minute(60000ms)
    
    }, null, 0, 60000);
    

    但是,如果您要从该线程更新任何 UI 代码不要忘记在 UI 线程上调用回

    WPF:

    var timer = new System.Threading.Timer((o) =>
    {
        Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate
        {
            // do stuff WPF UI safe
        });
    
    }, null, 0, 60000);
    

    Winform

    var timer = new System.Threading.Timer((o) =>
    {
        base.Invoke((Action)delegate
        {
            // do stuff Winforms UI safe
        });
    
    }, null, 0, 60000);
    

    例子:

    private void StartUpdateTimer()
    {
        var timer = new System.Threading.Timer((o) => 
        { 
            string ss = "gowtham " + DateTime.Now.ToString(); 
            Response.Write(ss); 
        }, null, 0,1000);
    }
    

    【讨论】:

    • +1 不错的答案。但是,如果do stuff 正在使用 UI,那么您还需要进入 UI 线程。见stackoverflow.com/questions/253138/…
    • +1 计时器更简单、更安全。希望 OP 可以使用这种方法,而不是深入研究多线程代码。
    • 我没有 +1 计时器是邪恶和坏主意,应该被禁止。
    • @Nahum Litvin,如果你想每分钟/每小时运行一次,定时器是最好的选择,长时间休眠后台线程只是愚蠢的,除非你有一个奥林匹克大小的线程池:)
    • 我的问题是当条件是这样的字符串 ss = "gowtham " + DateTime.Now.ToString(); var timer = new System.Threading.Timer((o) => { Response.Write(ss); }, null, 0,1000);将每 1ms 更改一次值
    【解决方案3】:

    Sleep 不会启动新线程,它会阻塞当前线程(在您的情况下为 UI 线程)给定的毫秒数。

    根据您的描述,您想启动新线程并可以在该线程中休眠。此外,使用计时器可能更容易。 MSDN Thread article 中提供了有关 Thread 对象的完整示例和信息:

    new Thread(ThreadFunction).Start(); 
    

    【讨论】:

      【解决方案4】:

      C# 或更多特别是 .NET 支持 MULTITHREADING。

      当您使用Thread.Sleep() 时,它将禁用使用Thread.Sleep() 的线程

      这里是使用'TPL' 午餐线程的示例,该线程每 60 秒对字符串进行一次采样

      System.Threading.Tasks.Task.Factory.StartNew(
      ()=>
      {
      System.Threading.Thread.Sleep(60000);
       ReadString()}
      )
      

      你应该记住,你需要保护你的字符串免受RACE CONDITION

      为此使用 C# lock

      【讨论】:

        【解决方案5】:

        不是每 60 秒启动一个新线程,而是使用一个线程,它在完成后休眠直到下一次运行。像这样的:

        Class Main{
        
        public void startObserverThread(){
           Thread t = new Thread(this.observerThread);
           t.start();
        }
        
        private DateTime lastRun = null;
        public void observerThread(){
           if (lastRun == null || DateTime.Now.Subtract(lastRun).Seconds >= 60){
               lastRun = DateTime.Now;
               //do thread work.
           }else{
               //check every second, if time elapsed
               Thread.sleep(1000);
           }
        }
        
        }
        

        如果需要更准确,请更改等待时间。 与在线程末尾重新安排新线程相比,最大的优势在于,您不需要关心任务本身的执行时间。如果需要 10 秒,线程将休眠 50 秒。如果需要 50 秒,则线程在完成任务工作后仅休眠 10 秒。

        【讨论】:

        • 你将如何向数据时间声明空值
        猜你喜欢
        • 1970-01-01
        • 2021-07-17
        • 1970-01-01
        • 1970-01-01
        • 2013-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-28
        相关资源
        最近更新 更多