Delegate/Invoke

Delegate method invoke problem

Page 1 of 1

2 Replies - 1676 Views - Last Post: 25 January 2010 - 01:55 AM Rate Topic: -----

#1 nsjoe  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 24-January 10

Delegate/Invoke

Post icon  Posted 24 January 2010 - 07:10 PM

I'm new to using delegates and invoke methods. Can someone please quickly identify what I'm missing here. I know this code is no where near completed right now, but as is, it's working for what I'm trying to test. Basically I'm creating a simple client application that is receiving a server message. Connections are fine, and the thread is receiving the server message. I just need to know how to properly marshal the message to my Form class control from my Client class.

It's the 'received.Invoke(response);' that isn't right somehow.

The form control is attempting to receive the message but it can't, because the marshalling isn't working. ('Cross-thread operation not valid:' error)

Maybe I need a second delegate for something??

HELP!!!

I've only added the code directly dealing with the thread.

Form code snippets:


	public partial class frmChat : Form
	{
		// create new client object
		private Client client = new Client();
 
		public frmChat()
		{
			InitializeComponent();
 
			client.received += new Client.receiveFunc(chatClientLibrary_Receieved);
			
 
		}
 
 
 
		private void menuItemConnect_Click(object sender, EventArgs e)
		{
			client.execute();
 
		}
 
		// method for outuptting message to textbox
		private void chatClientLibrary_Receieved(string msg) 
		{
 
			txtBoxConversation.Text = msg;
		}
	}





Client Class Code snippets:

public delegate void receiveFunc(string msg);
public event receiveFunc received;
 
 
Thread receiveThread = new Thread(new ThreadStart(threadListen));
 receiveThread.Start();
 
 
private void threadListen()
 {
 
	NetworkStream stream = this.client.GetStream();   // object to receive series of bytes
 
	byte[] inbuffer = new byte[256];
 
	 bool done = false;
 
	//while (stream.DataAvailable)
	while (!done)
	 {
 
		   while (stream.DataAvailable)
		   {
 
					int numRead = stream.Read(inbuffer, 0, inbuffer.Length);
 
					string response = Encoding.ASCII.GetString(inbuffer, 0, numRead);
 
					if (response == "Quit")
					{
						done = true;
					}
					else
					{
 
						received.Invoke(response);
 
					}
 
			  }
 
		 }   // end while instream.DataAvailable
 
	}




This post has been edited by nsjoe: 24 January 2010 - 07:33 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Delegate/Invoke

#2 manzoor  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 13
  • View blog
  • Posts: 468
  • Joined: 07-August 07

Re: Delegate/Invoke

Posted 24 January 2010 - 08:37 PM

You'll have to update the UI from thread on which it was created. One way to do it, is to use Control.Invoke method. So, declare a function which updates the UI, then declare a delegate with the same signature as of the function previously declared and then call:

txtBoxConversation.Invoke(new YourDelegateHere(receivedText));


Hope that helps.

This post has been edited by manzoor: 24 January 2010 - 08:37 PM

Was This Post Helpful? 0
  • +
  • -

#3 FlashM  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 382
  • View blog
  • Posts: 1,195
  • Joined: 03-December 09

Re: Delegate/Invoke

Posted 25 January 2010 - 01:55 AM

One way would be to do it like this:

private void btnStartThread_Click(object sender, System.EventArgs e)
{
	Thread t = new Thread(DoSomethingInOtherThread);
	t.Start();
}

private void DoSomethingInOtherThread()
{
	Thread.Sleep(3000);
	UpdateMessage("Done!");
}

private delegate void UpdateMessageDelegate(string message);

private void UpdateMessage(string msg)
{
	if (txtMessage.InvokeRequired)
	{
		txtMessage.Invoke(new UpdateMessageDelegate(UpdateMessage), msg);
	}
	else
	{
		txtMessage.Text = msg;
	}
}



But you can do this with less code, using anonymous method:

private void btnStartThread_Click(object sender, System.EventArgs e)
{
	Thread t = new Thread(DoSomethingInOtherThread);
	t.Start();
}

private void DoSomethingInOtherThread()
{
	Thread.Sleep(3000);
	txtMessage.Invoke(new MethodInvoker(delegate()
	{
		txtMessage.Text = "Done!";
	}));
}




Hope this helps.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1