Q
Problem solve Get help with specific problems with your technologies, process and projects.

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

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.

Dig Deeper on C# programming language

Have a question for an expert?

Please add a title for your question

Get answers from a TechTarget expert on whatever's puzzling you.

You will be able to add details on the next page.

Start the conversation

Send me notifications when other members comment.

Please create a username to comment.

-ADS BY GOOGLE

SearchCloudComputing

SearchSoftwareQuality

TheServerSide.com

Close