【问题标题】:Timer just works if call MessageBox.Show()如果调用 MessageBox.Show(),计时器才有效
【发布时间】:2011-12-31 12:24:27
【问题描述】:

这怎么可能?我有一个计时器,如果没有网络连接,就会调用它,如方法 down:

public void Foo() {
     for (int i = 0, count = MailList.CheckedItems.Count; i < count; i++) {
         /* Check for network available connection in computer
              public bool HasConnection() {
                return System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();
             }       
         */
         if (!net.HasConnection()) { 
              SearchNetworkConnection.Start(); //start the timer 
         }
     }
}

Timer_Tick方法:

   private void SearchNetworkConnection_Tick(object sender, EventArgs e) {
            ++ATTEMPRECONNECT;

            string currentState = "attemp reconnect.."; 
            MessageBox.Show(currentState, "..", MessageBoxButtons.OK, MessageBoxIcon.Warning);

            if (ATTEMPRECONNECT >= ATTEMPRECONNECTLIMIT) {
                //do abort all process 
                SearchNetworkConnection.Stop();
            }
      }

这很奇怪,只要我在SearchNetworkConnection.Start() 之后调用MessageBox.Show()

换句话说,它不起作用,定时器不会运行:

if (!net.HasConnection()) { 
        SearchNetworkConnection.Start();
   }

调用MessageBox.Show(),它工作正常:

if (!net.HasConnection()) { 
        SearchNetworkConnection.Start();
        MessageBox.Show("lol");
 }

如果有用,Foo() 方法在线程上运行。

更新

所以,我觉得这有点奇怪。我为一些测试写了一个简单的代码。我很惊讶,错误还在继续。下面的代码工作正常,但如果你改变了顺序

timer.Start();
DialogResult result = MessageBox.Show(text, caption);

DialogResult result = MessageBox.Show(text, caption);
timer.Start();

它不起作用,计时器不启动。

public static DialogResult Show(string text, string caption,int dellay)
        {

            Timer timer = new Timer();
            timer.Interval = dellay;
            timer.Start();
            DialogResult result = MessageBox.Show(text, caption);
            timer.Tick += new EventHandler(delegate
             {
                    IntPtr handle = FindWindow(null, caption);

                    if (handle != IntPtr.Zero)
                    {
                        IntPtr hresult = SendMessage(handle, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);

                        if (hresult == IntPtr.Zero)
                        {
                            timer.Stop();
                            timer.Dispose();
                        }
                    }
            });

            return result;
        }

【问题讨论】:

  • 即使计时器已经启动,您的 Foo 方法也会调用 Timer.Start。调用Start 是否有可能重置时间间隔?也许你应该写if (!net.HasConnection() &amp;&amp; !SearchNetworkConnection.Enabled)

标签: c# .net winforms timer


【解决方案1】:

您的计时器需要一个消息泵才能运行。 MessageBox.Show() 提供了一个。

但您需要完全避免使用消息框(查看 Systems.Diagnostsics.Debug.Print())。

您可能应该看看其他计时器(System.Threading、System.Timers)。


第 2 部分

您声明Foo() 在线程上运行。听起来不错。
但是你的 Windows.Forms.Timer 需要一个 MessageBox 来运行这一事实意味着你以某种方式阻塞了你的主线程。所以你的问题不在发布的代码中,而是在其他地方。

【讨论】:

  • @Henk Holterman:什么是“消息泵”?起初我尝试在 MessageBox 之后使用 Debug.WriteLine() 等。我相信与 .Print() 方法不会有太大的不同。
  • 是的,你知道的。 while (GetMessage()) { Dispatchmessage(); } 。每个 Windows 应用程序都有一个,通常在 Application.Run() 中。
  • @Jack:是的,Debug.WriteLine/.Print 不能解决您的直接问题。只需改进您的程序即可。
  • 嗯,我认为计时器控件看起来是这种情况下最好的解决方案,而不是线程(虽然它的工作原理很像)。
猜你喜欢
  • 2013-09-05
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 2011-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多