Form freezes when using asynchronous callback mechanism

Form freezes when using asynchronous callback mechanism

I'm using an asynchronous callback mechanism to receive data from the socket. Once the data is received, I parse the data, and if certain information is received, I open a new form. Everything goes fine until the form is opened. The opened form seems to freeze and does not refresh (no errors are generated). Part of the code is included below. (Please let me know if you need the entire source code.)
private void Receive() 
{
try
{				 if  ( callbackProc == null )
  callbackProc = new   
   AsyncCallback(ReceiveCallback);

   StateObject state=new StateObject();
   state.workSocket = s;  
   s.BeginReceive(state.buffer, 
     0, StateObject.BufferSize, 
     SocketFlags.None, 
     callbackProc, state);	
  }  
  catch (Exception ex) 
{
 MessageBox.Show(ex.Message);
}
}

private void ReceiveCallback (IAsyncResult ar) 
{
try 
{

StateObject state = (StateObject) 
   ar.AsyncState;

int bytesRead = 
  state.workSocket.EndReceive(ar);

string szData = 
System.Text.Encoding.Unicode.GetString(state.buffer, 0, bytesRead);

  frmNew n = new frmNew();
  n.show();

  Receive();
} 
catch (Exception ex) 
{
throw new Exception(ex.Message);
	}	
}

    Requires Free Membership to View

    When you register, you'll begin receiving targeted emails from my team of award-winning writers. Our goal is to provide a unique online resource for developers, architects and development managers tasked with building and maintaining enterprise applications using Visual Basic, C# and the Microsoft .NET platform.

    Hannah Smalltree, Editorial Director

    By submitting your registration information to SearchWinDevelopment.com you agree to receive email communications from TechTarget and TechTarget partners. We encourage you to read our Privacy Policy which contains important disclosures about how we collect and use your registration and other information. If you reside outside of the United States, by submitting this registration information you consent to having your personal data transferred to and processed in the United States. Your use of SearchWinDevelopment.com is governed by our Terms of Use. You may contact us at webmaster@TechTarget.com.

Basically, the problem is that all WinForm controls (including the Form) must run from the main thread, the one that started the application. Your callback is NOT on that thread, thus it locks everything. This can be solved easily. To invoke an arbitrary method from the main thread, you can use the main form Invoke method, passing a delegate to the method to call. Needless to say, you need to have a delegate matching the target method signature. So for the Show method, you use the following code:
delegate void ShowDelegate();

private void ReceiveCallback (IAsyncResult ar) 
{
  try 
  {
    //do your work
   frmNew n = new frmNew();
   this.Invoke(new ShowDelegate(n.Show));

    //the rest goes here

I'm assuming your callback method is placed on the main form; that's why I use this.Invoke, but that's not a requisite. As long as you can get a reference to it (through a static variable or whatever), it's OK.

This was first published in October 2003