简体   繁体   中英

Timer just works if call MessageBox.Show()

How is this possible? I have a timer that is called if have no network connection,as in method 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 
         }
     }
}

and The _Tick method of Timer :

   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();
            }
      }

That works oddly, just if I call the MessageBox.Show() after SearchNetworkConnection.Start() .

In other words, it does not work, the Timer won't run:

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

calling MessageBox.Show() , it works fine:

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

if it can be useful, Foo() method run on thread.

Update

So, I think it's a little strange. I wrote a simple code for some tests. and I'm surprise,the mistake continue. The below code works fine, but if you do change the order

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

to

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

it does not work, the timer does not 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;
        }

Your Timer needs a messagepump to run. MessageBox.Show() is providing one.

But you'll want to avoid messageboxes altogether (look at Systems.Diagnostsics.Debug.Print()).

You should probably take a look at other timers (System.Threading, System.Timers).


Part 2

You state that Foo() runs on a Thread. That sounds OK.
But the fact that your Windows.Forms.Timer needs a MessageBox to function means that you are somehow blocking your main thread. So your problem is not in the posted code but somewhere else.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM