当线程在 main 上运行时,System.Windows.Forms 计时器不起作用

Posted

技术标签:

【中文标题】当线程在 main 上运行时,System.Windows.Forms 计时器不起作用【英文标题】:System.Windows.Forms Timer is not functioning when a thread is running on main 【发布时间】:2016-07-23 12:00:51 【问题描述】:

我想问问你们中的任何人是否尝试过这种情况。我用c#开发了一个windows应用程序。在主程序(Program.cs)中,我添加了一个线程互斥锁,只是为了多任务处理在它下执行的许多操作。

//under Program.cs
public static FormOneInstance frmOneInstance;
    static void Main()
    
         t = new Thread(new ThreadStart(CreateInputOutput));
         t.Start();
    
    public static void CreateInputOutput()
    
                try
                
                    mutex.WaitOne(); 
                    ExecuteManyOperationsHere(); 
                
                finally
                
                    mutex.ReleaseMutex();
                    Thread.CurrentThread.Abort(); //Has ThreadAbortException here
                    t = null;
                
      



  public static void ExecuteManyOperationsHere()
    
      frmOneInstance  =new FormOneInstance (); //this has lot of execution on formLoad that includes ShowSummary()
    

在我的另一个表单 FormOneInstance 类中,我使用了 System.Windows.Forms Timer

 private void timer1_Tick(object sender, EventArgs e)
        

            ShowSummary();
        

现在,我想将主线程和 UI 中的线程分开。 谢谢!

【问题讨论】:

您需要此计时器的消息循环...请注意,目前还不清楚为什么您为控制台应用程序选择该计时器...以及 mutex.WaitOne 应该代表什么代码。阅读minimal reproducible example 指导以改进问题可能是个好主意。 这不是控制台应用程序。为什么需要消息循环? 互斥锁是两个或多个线程同时访问共享资源的一种同步机制。我没有看到多个线程使用互斥锁,也没有看到正在同步的资源。如果 timer1_Tick 被用于显示来自另一个线程的进度/结果,那么它不太可能那么容易。你熟悉后台工作者吗? 是的,我以前使用过,但我的应用程序仍然挂起。所以,当我尝试使用互斥锁时,它运行顺利 @user34660 我已经更新了我的帖子。 【参考方案1】:

Windows Forms Timer 在 ui 线程上运行,只有一个可以看到 this SO post。

参见例如 MSDN 上的 Threading.Timer

您可以使用没有这些东西的计时器。但一定要在计时器代码想要更改 ui 中显示的值时调用回 ui 线程

myTimer= new Timer( handleTimer, null, timerIntervall, Timeout.Infinite );

然后您可以创建一个方法,在 ui 线程上调用 CreateInputOutput 方法以显示新的 ui 元素

public void handleTimer(object State)

// PLace here the blocking code which shoudl not block the ui
this.invoke(...)  // here you can call the method which should be run un the ui thread. Like creating new forms

更多详情请参阅这篇关于threading timer的帖子

【讨论】:

【参考方案2】:

由于不清楚您的要求是什么,我假设您真正想要使用的是BackgroundWorker。以下也有样片。

BackgroundWorker.ReportProgress Method (Int32, Object) (System.ComponentModel)

Walkthrough: Multithreading with the BackgroundWorker Component (C# and Visual Basic)

How to: Run an Operation in the Background

【讨论】:

以上是关于当线程在 main 上运行时,System.Windows.Forms 计时器不起作用的主要内容,如果未能解决你的问题,请参考以下文章

导航到另一个 xib 时未在 AppKit(主)线程问题上运行

java 后台线程自己断掉一般是啥由原因引起的?

多线程核心数据:“主”上下文线程

跟踪程序堕胎的工具

如何修复运行时错误-线程“main”java.util.NoSuchElementException中的异常

Java并发基础知识