Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Windows Forms / WinForm General / February 2007

Tip: Looking for answers? Try searching our database.

help explain this winform behaviour

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
dadizhu@gmail.com - 03 Feb 2007 04:38 GMT
Hi, everyone.  I ran into an UI freeze issue with threading and
simplied the problem down to the following sample code.  The logic is
as follows:

1.  The main UI thread creates a non-UI STA thread(m_MainThread).
2.  Then the non-UI thread runs and creates derived winform and holds
a reference to the winform.  NOTE: I don't call Application.Run()
because I don't need a message pump on this "hidden form" in my
application.  I rely on the form's STA thread owner to pump and
dispatch non-COM messages to the form window on a WaitOne() call.
This works fine.  I can send and receive messages to external win32
process using the hidden form.

The code below works fine in .NET 1.1, but causes UI freeze issue
in .NET 2.0 outside of the debugger.  To produce the freeze behaviour,
I do the following:

1.  Run the winform test app below outside of debugger.
2.  Click on the Start button to create the non-UI thread(which
creates the hidden form)
3.  right click on Desktop -> Properties -> Settings -> change your
screen resolution to something less and click OK
4.  When asked if you want to keep the setting, click NO to go back.

At this point, you will notice that the main form is now
frozen(verified with spy++ that it doesn't get any messages).  It
looks like it's deactivated somehow.  You can't move the window and
the form won't paint properly if you overlap it with another window.

The same code below doesn't have the problem in .NET 1.1.  Also, the
problem doesn't occur in .NET 2.0 if you run  it under the debugger.

If I don't create the hidden winform, there is no problem.

Can someone explain what's happening?  Thanks.

================= Code Starts Here =================

   public partial class Form1 : Form
   {
       AutoResetEvent m_MainThreadStopEvent = new
AutoResetEvent(false);
       Thread m_MainThread = null;
       HiddenForm m_WorkerHiddenForm = null;

       public Form1()
       {
           InitializeComponent();
       }

       private void Start()
       {
           m_MainThread = new Thread(new
ThreadStart(MainThreadStart));
           m_MainThread.Name = "My Main Thread";
           m_MainThread.SetApartmentState(ApartmentState.STA);
           m_MainThread.Start();
       }

       private void Stop()
       {
           m_MainThreadStopEvent.Set();
       }

       private void MainThreadStart()
       {
           System.Diagnostics.Debug.WriteLine("Created Main
Thread ... " + DateTime.Now.ToLongTimeString());
           m_WorkerHiddenForm = new HiddenForm();

           while (!m_MainThreadStopEvent.WaitOne(5000, true))
           {
               System.Diagnostics.Debug.WriteLine("::MainThread ... "
+ DateTime.Now.ToLongTimeString());
           }
           m_WorkerHiddenForm.Close();

           System.Diagnostics.Debug.WriteLine("Stopped Main
Thread ... " + DateTime.Now.ToLongTimeString());
       }

       private void btnStart_Click(object sender, EventArgs e)
       {
           Start();
       }

       private void btnStop_Click(object sender, EventArgs e)
       {
           Stop();
       }

       private void Form1_FormClosing(object sender,
FormClosingEventArgs e)
       {
           Stop();
       }
   }

   public class HiddenForm : Form
   {
       int m_WindowHandle;
       public HiddenForm()
       {
           m_WindowHandle = this.Handle.ToInt32();
       }

       protected override void WndProc(ref Message msg)
       {
           base.WndProc(ref msg);
       }
   }
ClayB - 05 Feb 2007 11:09 GMT
Just something to try. In your hidden form code, if you an
InvokeRequired check to the WndProc override, does it verify you are
on the proper thread?

protected override void WndProc(ref Message msg)
       {
           if(this.InvokeRequired())
                 throw new Exception("Wrong thread");
           base.WndProc(ref msg);
       }

===================
Clay Burch
Syncfusion, Inc.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.