Click here to Skip to main content
Email Password   helpLost your password?

Introduction

You are developing this shiny new multithreaded .NET application that has this spanking new UI. You are done coding and it's time for giving a demo to your boss. And while running the demo, the UI hangs. Just hangs. Damn it, you say, it was working fine on my PC. You go back to your source and try to figure out why that happened. After a lot of poking around/debugging/swearing, you notice that you call this simple property on a control and it never returns. Or sometimes, it returns, but doesn't update the UI correctly. You then read something about calling BeginInvoke. What's that, you wonder. This article will try to answer that. Note that this article will be dealing with the BeginInvoke method on the System.Windows.Forms.Control and not the BeginInvoke method that can be called on delegates to run them asynchronously.

What does BeginInvoke do?

According to MSDN, Control.BeginInvoke "Executes the specified delegate asynchronously on the thread that the control's underlying handle was created on". It basically takes a delegate and runs it on the thread that created the control on which you called BeginInvoke. Why do I need to do that, you ask. To understand why, you have to know about how Windows processes UI actions.

Message queue and Message pumping

Every Windows application you create is provided with a thread on startup. It's this thread that calls the Main method of your application. For a console application, you can write Main to accept user input and process them. For a GUI application, things are radically different. GUI applications are event based, which means that there needs to be some entity to process and fire events. Windows manages this by creating a message queue for your application. All UI related actions get translated to messages that get posted to this message queue 1. Now, you need someone to read the messages from the queue and call appropriate event handlers. That's what a message pump is for. It basically is a loop that waits for someone to post a message to the queue. Once someone does, it dequeues it and calls the associated event handler. It can be thought of as:

    Message message = null;
    while ((message = GetNextMessage()) != null)
    {
        ProcessMessage(message);
    }
}

Where does the message pump run? On the Main thread, of course. So a typical GUI application, after doing some initialization in the Main method, will then start running the message pump. The while loop will exit only when the application closes, so that means the Main thread can't do anything else once the message pump starts. In .NET GUI applications, the Application.Run method takes care of message pumping. You'll see that every .NET GUI application's Main method looks like this:

public static void Main(string[] args)
{
   Form f = new Form();
   Application.Run(f);
}

That fits in nicely with our theory, Application.Run will run the message loop on the thread on which it is called. In our case, it is the main thread and you can verify that the thread doesn't get past Application.Run until the application closes by running it under the debugger. As an aside, modal dialogs (shown using Form.ShowDialog) have their own message pump whereas modeless dialogs (shown using Form.Show) don't. Which means that you can call Form.ShowDialog from any thread but Form.Show requires the calling thread to be running a message pump. Note that if you call Form.Show from a UI event handler, both the new form and the current form will be sharing the same message pump, which means that if one form is stuck executing one of the event handlers, the other one won't be usable too.

The One Rule

One of the cardinal rules of Windows GUI programming is that only the thread that created a control can access and/or modify its contents (except for a few documented exceptions). Try doing it from any other thread and you'll get unpredictable behavior ranging from deadlock, to exceptions to a half updated UI. The right way then to update a control from another thread is to post an appropriate message to the application message queue. When the message pump gets around to executing that message, the control will get updated, on the same thread that created it (remember, the message pump runs on the main thread).

Let's go deeper into the Win32 world. There are two fundamental Win32 API calls to access and/or modify a control, SendMessage and PostMessage. There is a big difference in the way the two execute. The major difference is that SendMessage blocks the caller till the message gets processed by the message pump whereas PostMessage returns immediately. The subtle but important difference is that messages sent using SendMessage aren't queued in the message queue whereas PostMessage messages are. SendMessage messages are directly "sent" to the message pump. The message pump retrieves and processes messages sent using SendMessage before looking into those in the message queue. Effectively, there are then two queues, one for SendMessage messages and one for PostMessage messages (which is what we call the message queue). The message pump processes all messages in the first queue before starting with the second. An interesting observation is that if code does a SendMessage from within the message pumping thread, the window procedure gets called directly, that is, it doesn't go through the message pump.

Why The One Rule Exists

Now it should be fairly obvious as to why the rule is around. The first reason is the blocking nature of SendMessage. Imagine a situation where the message pumping thread is waiting for your thread to complete and your thread does a SendMessage. SendMessage will return only after the message pump has processed the message, but the message pump is stuck waiting for the thread to complete. Deadlock, and we know it's not exactly fun.

In .NET, property/method calls on a Control object translate to SendMessage calls, so you can easily see how it can turn nasty. PostMessage posts a message to the queue and returns immediately, so there is no chance of deadlock.

The second reason is more subtle. Because there are effectively two queues, it's quite possible that at one point in time, both queues have the same message but with different parameters. Let's assume the message sets the text of a control and that you've used SendMessage. The message pump first processes SendMessage messages and the text is set to a particular value. It next starts processing messages in the message queue (sent using PostMessage). Along comes the same message from the message queue and it overwrites the previous value with its parameters. You never know when the message from the message queue was posted, it's very much possible that it was posted before you issued SendMessage. In that case, your most recent update gets overwritten with an older one. If the SendMessage message was to read the text of the control, it'll return a wrong value because the PostMessage message that executes later will set it to something else and that's what will be visible in the UI.

If instead of SendMessage, you had used PostMessage, then both messages would have gone to the same queue and barring race conditions as to who posted first to the queue, the order would have been preserved.

There is one other issue with using SendMessage that is not obvious at all. SendMessage, while blocking the current thread, continues to process messages that are sent to the message pump using SendMessage or one of the functions that send nonqueued[^] messages. This means that your code must be prepared to handle incoming messages when blocked on a SendMessage call. This can cause problems if your code depends on SendMessage to be a truly blocking function and doesn't use any other synchronization mechanism. For e.g., consider this piece of code:

void ButtonClick_Handler(object sender, EventArgs e)
{
   int val = count; // count is a class member variable
   SendMessage(...);
   Console.WriteLine(val == count); // Surprise, val != count can happen!
}

void SomeOtherMessageHandler()
{
   count++;
}

When the above piece of code is blocking on the SendMessage and someone else does a SendMessage to this application that causes SomeOtherMessageHandler to execute, then val will not be equal to count. The core of the issue is that SomeOtherMessageHandler will execute even if ButtonClick_Handler is blocked on SendMessage, which is not what most people expect. To avoid such problems, Windows provides the SendMessageTimeout API function, which when called with the right parameters, will prevent pumping of nonqueued messages when blocked on sending a message. However, all .NET UI controls use SendMessage, so you can't avoid the problem, unless you are planning on doing P/Invoke.

If you're still not convinced that SendMessage from a different thread is not a great idea, see this post for a great practical example.

Why and when to call BeginInvoke

With all that stuff inside our head now, we can easily figure out the reason for the existence of BeginInvoke. It essentially does a PostMessage. Whenever you want to update a control from a thread that didn't create it, instead of directly calling the method/property to update it, you need to wrap it in a BeginInvoke call. According to MSDN: "There are four methods on a control that are safe to call from any thread: Invoke, BeginInvoke, EndInvoke, and CreateGraphics. For all other method calls, you should use one of the invoke methods to marshal the call to the control's thread". One of the invoke methods, you say, what are the others? Well, the Control class provides one property and two methods to do the stuff we discussed.

A typical piece of code using BeginInvoke will look like this:

public class FormFoo : Form
{
   Label label = new Label();
   public static void Main()
   {
       Application.Run(new FormFoo());
   }

   public FormFoo()
   {
      InitializeComponent();

      Thread t = new Thread(new ThreadStart(ChangeLabel));
      t.Start();
   }

   private void ChangeLabel()
   {
       for (int i = 0; i<100; ++i)
       {
          SetLabelText(i);
          Thread.Sleep(1000);
       }
   }
   private delegate void SetLabelTextDelegate(int number);
   private void SetLabelText(int number)
   {
      // label.Text = number.ToString();
      // Do NOT do this, as we are on a different thread.

      // Check if we need to call BeginInvoke.
      if (this.InvokeRequired)
      {
         // Pass the same function to BeginInvoke,
         // but the call would come on the correct
         // thread and InvokeRequired will be false.
         this.BeginInvoke(new SetLabelTextDelegate(SetLabelText), 
                                          new object[] {number});

         return;
      }

      label.Text = number.ToString();
   }
}

Assigning a value to label.Text directly in SetLabelText will result in a SendMessage to the underlying control from the current thread and we saw in excruciating detail why it is troublesome. So we use BeginInvoke, passing the same function as the delegate parameter, which will post a message to the handle of this. When the message pump dispatches the message, it'll call SetLabelText and in that invocation, InvokeRequired will return false. We then set the Label's text, confident that we are on the right thread.

The BCL provides a MethodInvoker delegate, which you can use if your wrapped function takes no parameters and returns void. You can also reuse the EventHandler delegate in case your wrapped function's signature matches it. The MSDN documentation says using these delegates instead of our own custom delegates will result in faster execution.

Both BeginInvoke and Invoke check if they are called on the correct thread (the thread that created the control) and if so, directly update the control instead of doing the PostMessage thing. Apart from performance benefits, it also prevents deadlock if you call Invoke from within a method already running on the UI thread.

Invoke and BeginInvoke

Which function to use, you ask. It really depends on your requirement. If you want your UI update to complete before proceeding, you use Invoke. If there is no such requirement, I'd suggest using BeginInvoke, as it makes the thread calling it seemingly "faster". There are a few gotcha's with BeginInvoke though.

Note that the above points are valid for any function that you run as a thread. They're not so obvious when using BeginInvoke, because BeginInvoke doesn't actually create a thread and instead runs the wrapped function on an already existing thread (the UI thread). It still means that there are two threads, so you want to take the same care protecting your shared variables.

If your code is based on .NET 1.1 (including SP1), there is a bug in the framework implementation of Invoke which could cause it to hang indefinitely on multiprocessor machines. The bug has been fixed in .NET 2.0 and as this KB article says, there is a hotfix available for 1.1, but it can only be obtained by calling PSS. You could always call BeginInvoke and use a custom signalling mechanism instead. Here is the description of the actual problem, in case you're interested.

A warning

Control.BeginInvoke, which is what we have been discussing so far, works slightly differently from Delegate.BeginInvoke. Delegate.BeginInvoke grabs a threadpool thread and executes the passed delegate on that thread. Control.BeginInvoke does not use a threadpool thread, it does a PostMessage to the target window handle and returns. This is crucial because if it uses threads, then there is no guarantee to the order in which messages are posted and processed by the application. Also, unlike Delegate.BeginInvoke, Control.BeginInvoke doesn't require every call to BeginInvoke to be matched by an EndInvoke. Of course, if you are using the return value of the method and/or out or ref values, then you need to call it anyway.

Conclusion

Judging from the number of posts in the C# forum resulting from the improper use of BeginInvoke, this seems to be a poorly understood topic. Hopefully this article will help clarify things a bit. In .NET 2.0, the CLR straightaway throws an exception if you attempt to do a cross thread UI update. In fact, I'd suggest compiling your app for the 2.0 platform and running the app through all possible scenarios, just to make sure there are no inadvertent cross thread UI updates.

Appendix

Note 1 Not entirely true, as explained later in the article. Some of the messages are posted to the message queue (PostMessage) and some are directly sent to the message pump (SendMessage). Sent messages are processed first before processing messages in the message queue.

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralWon't Thread.Sleep delay finish of execution?
Onur Guzel
0:56 7 Aug '09  
Nice article, thanks. However though you use BeginInvoke or Invoke, based on my expriments on old PCs, if the job is CPU-intensive task and consumes almost %100 CPU, yes the UI remains responsive but if you use Thread.Sleep the execution will finish much more later.

But it seems using Thread.Sleep is required because your application(and form) won't let any any message process while CPU is in use (%100) without it. Thread.Sleep seems let CPU take a short breath and execution can continue though it finishes times and times later.

Try:
Have a job that takes %100 CPU (preferably on a single-core P4 machine, counting numbers to 5000), and remove "thread.sleep", while multi-threaded job is in progress you cannot move form, system hangs. But if you use Thread.Sleep form is moved around the screen with no problem but the task is finished later.

A minor but important detail in my idea.

Thanks.
GeneralFor hanging windows
mblaga
22:24 6 Nov '07  
I found two useful links about the Controls hanging. I hope this will give some of you some answers to your questions.

http://krgreenlee.blogspot.com/2007/09/onuserpreferencechanged-hang.html
http://ikriv.com:8765/en/prog/info/dotnet/MysteriousHang.html

This people did a very good job to explain what really happens.

Best regards
Mircea
GeneralHow windows processes mess ?
Florian G.
20:03 25 Oct '07  
Hello,

I've around on the net to find some good info about those invoke matters, and I must admit that your post is one of the best.

Nevertheless something is confusing for me since I read this post.

It is written "You have to know how windows processes messages" as if the rule that only creating thread can launch a control's method is a common Windows rule.

I don't know so much about that, but if so, why does the exception of invalid cross-thread operation have been available only from .NET 2.0 ?

Moreover why is there no similar method in JAVA or in C++ or C(except in .NET).

I don't know so much, but I guess that this talk is just related to Microsoft's way to implement controls in .NET. So this is just related to .NET library, and if we are using any other development tool, it may not exist.

Am I right ?

I may be wrong, then if someone could answer to this question:

How to get back the owning thread of a windows control in JAVA or C++ ?
GeneralBeginInvoke doesn't return immediately.
fmatias
6:17 4 Oct '07  
Hi all,

I'm working in a real-time response project and I have found that the method Control.BeginInvoke doesn't return immediately.

I'm using a thread that is awakened by the driver that manages an external card (TV card). From inside this thread I'm trying to send some information to my graphic interface using asynchronous delegate invokation. I have found the following issue:

When the window is busy doing something (for example minimizing or maximizing) the thread that call Control.BeginInvoke hungs its execution a long time (250 millisecons in my system)
I have a big problem because my thread need to work at a rate of 25 times per seconds. So I have 40 milliseconds to perform all my operations. I'm including some sample code that exposes my problem. Run the code and minimize and maximize some times, then close the application and the resulting log file.

I also tried to use PostMessage API call with the same result. The thread hungs when I post a message to the windows handle of the Form.

Am I doing something wrong?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace TestInvokeFromInsideThread
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

// Never-ending thread
private static Thread thLoop = null;

// Flags for exiting thread
private bool flagExitThread = false;

// Array of times
private int[] invokeTimes;
private int numTimes;

// System frequency
long sysFreq;

private void Form1_Load(object sender, EventArgs e)
{
invokeTimes = new int[10000];
numTimes = 0;
QueryPerformanceFrequency(out sysFreq);
thLoop = new Thread(new ThreadStart(ThreadLoop));
thLoop.Priority = ThreadPriority.Highest;
thLoop.Start();
}

[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);

[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(out long lpFrequency);

private delegate void DoSomethingDelegate();

private void ThreadLoop()
{
long t1, t2;
Delegate del = new DoSomethingDelegate(DoSomething);

while (true)
{
Thread.Sleep(40);

// Invoke asynchronous delegate
QueryPerformanceCounter(out t1);
this.BeginInvoke(del);
QueryPerformanceCounter(out t2);

// Add time (in microseconds) to statistics
if (numTimes < 10000)
{
invokeTimes[numTimes] = (int)((t2 - t1) * 1e6 / sysFreq);
++numTimes;
}

if (flagExitThread)
break;
}
}

private void DoSomething()
{
// Do something
}

private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
flagExitThread = true;
thLoop.Join();

// Save registry times in log file
using (StreamWriter sw = File.CreateText("Times.txt"))
{
sw.WriteLine("#Time Ticks");
sw.WriteLine("===== ========");
for (int n = 0; n < numTimes; n++)
sw.WriteLine("{0,-5} {1,8}", n + 1, invokeTimes[n]);
}
}
}
}

GeneralWhat about ForeColor
Vincent DUVERNET (Nolmë Informatique)
8:05 30 Sep '07  
on invalid cross thread operation, we always see the same way to solve the problem for setting up control text.

if we want to change color, source code looks like this :
delegate void SetForeColorCallback(Control output, Color foreColor);

private void SetForeColor(Control output, Color foreColor)
{
if (output.InvokeRequired)
{
SetForeColorCallback d = new SetForeColorCallback(SetForeColor);
this.Invoke(d, new object[] { output, foreColor});
}
else
{
output.ForeColor = foreColor;
}
}

which can be used for all controls derived from Control class.
To change Font, do the same way.

The question is :

It's really boring writing this part of code so why no faster solution (library,interface,utility class) exist ?
GeneralControl.BeginInvoke callback?
logan1337
9:33 20 Sep '07  
Hi. Is there an easy way to be notified when an asynchronous call using Control.BeginInvoke() completes? I really want to avoid polling the IAsyncResult.IsCompleted property.
QuestionAvoid using SendMessage from a thread ?
debubiswas
14:20 18 Sep '07  
As I understand, this article proves that avoiding calling "SendMessage" from any thread (regardless of UI thread or control updates) is good programming practice.

Also if .NET did not have control properties updates implemented as "SendMessage" (but "PostMessage" calls) calls, we would have no issues. The only reason messaging ("Post or Send") is needed here for control updates is because the caller thread and control thread are different threads. As stated, if the control is updated within the same UI thread, it need not go through "messaging" and can be updated directly.

Senthil, please correct me I am wrong in any of these statements.

Debabrata Biswas
GeneralBad Link
devvvy
22:25 11 Sep '07  
"If you're still not convinced that SendMessage from a different thread is not a great idea, see this post for a great practical example."
Bad link -- *this*

Could you fix it please I want to see why updating from a differnt thread is a bad idea.
GeneralRe: Bad Link
S. Senthil Kumar
23:54 11 Sep '07  
Here is the link[^]. I'll update the article later.

Regards
Senthil [MVP - Visual C#]
_____________________________
My Blog | My Articles | My Flickr | WinMacro

GeneralReference here. Re: Bad Link
devvvy
17:53 12 Sep '07  
Thanks and for sake of easy reference ... Quoting "Ian Griffiths":
Well this article gets to the core of it - it's all to do with the underlying Win32 windowing architecture.

But to expand a little, here'
s a specific way in which something as simple as reading the Text property of a TextBox can go wrong. (And this isn't theoretical. I wrote an example that demonstrates the wrong values being returned.)

If you read the Text property of a TextBox, the TextBox class relies on the underlying Win32 control to hold the text, so it must send messages to that HWND to retrieve the text. It sends two. One, WM_GETTEXTLENGTH, to find out how much text there is, and another, WM_GETTEXT to read the actual text.

If you'
re running on the UI thread, this is safe. You are guaranteed that the text won't change in between these two messages, because the only way that the contents of a textbox can change is if a message is sent to the textbox. Messages are always delivered by windows on the UI thread, so as long as you control the UI thread, you can be certain it won't change.

But if you're on the wrong thread, it's different. Windows Forms sends the WM_GETTEXTLENGTH message as before, but Win32 notices you're on the wrong thread, so it sends that message via the message queue, and makes your thread wait until the UI thread handles that message. At some point the UI thread will handle the message, and at some point after that your thread will get a response. Your thread will still be inside Windows Forms at this point, and will then send a WM_GETTEXT message.

But the problem is, in between the UI thread handling the WM_GETTEXTLENGTH message, and your thread getting around to sending a WM_GETTEXT message, some other messages might have got into the message queue, and those might cause the contents of the TextBox to change.

The result is that the amount of text in the TextBox might be different, so the buffer that Windows Forms passes in the WM_GETTEXT message might be too small. The result will be that the text is truncated and you see the wrong value.

This is a fairly benign example, because it doesn'
t crash. It does result in bad data, but it's pretty unusual for this to occur in practice. And it won't corrupt the heap or anything nasty like that - you just get a truncated string.

The real trouble starts when code starts acquiring locks, as quite often happens in multithreaded applications. You can end up with the really nasty situation where a worker thread is in posession of a lock, and is waiting for the UI thread to respond to a message, but the UI thread is waiting to acquire the same lock. You can deadlock even with just one lock!

This happens because Win32 funnels all messages through the UI thread, making the UI thread act as a kind of implicitly locked shared resource. Any time you do anything to a control you are effectively locking on that resource, which risks deadlock.

--
Ian Griffiths
DevelopMentor



devy

GeneralAwesome Article
f r i s c h
23:31 29 Aug '07  
That article really helps me, we just discussed the difference between BeginInvoke and Invoke and your article helped us a lot.

Thank you.
GeneralThank you very much!!!
mishasoft
2:19 16 Jul '07  
I've used GUI inter-thread issues without deep understanding. This topic has ordered all things in my mind. Thank you very much!!!

Best regards,
Michael Gershkovich

GeneralGREAT ARTICLE
adamAFA46
12:15 30 May '07  
Thanks, this is a fantastic article!
GeneralRe: GREAT ARTICLE
entraped.isoLated
0:48 16 Nov '07  
exactly! i get rid of all the confusions. awesome man keep it up!
GeneralHanging BeginInvoke as well...
Petru66
6:48 3 May '07  
Well, I certainly got into the deadlock of Invoke, on my CoreDuo. As I had (and have) no intention to phone Microsoft for bug fixes which should be readily available, I tried the solution with BeginInvoke.

I needed, though, some kind of synch - that is, the working thread that initiates the GUI call must not continue until the invocation finished. So I called the BeginInvoke with an accompanying EndInvoke:

// delg is a delegate
IAsyncResult res = this.BeginInvoke(delg, new object[]{pArray});
res.AsyncWaitHandle.WaitOne(); // this might as well be outcommented, I believe
this.EndInvoke(res);

Well, it hanged.

The issue occurs when a popup menu is shown and the mouse hovers over its items. I believe that the GUI is busy with showing the popup correctly and it "does not have time" to solve invokations. So these things are probably not even placed in one of the queues you mention in the article.

...Which, by the way, is pretty annoying. Because right now I am out of ideas.

Petru
GeneralRe: Hanging BeginInvoke as well...
S. Senthil Kumar
8:08 3 May '07  
EndInvoke in turn calls WaitOne, and it's the WaitOne that causes the hang, so you cannot use EndInvoke. Instead, you could try using some other signaling mechanism yourself, like an AutoResetEvent. Make the worker thread initiating the GUI call wait on the event and set it at the end of the function that runs on the UI thread.

Regards
Senthil [MVP - Visual C#]
_____________________________
My Blog | My Articles | My Flickr | WinMacro

GeneralRe: Hanging BeginInvoke as well...
Petru66
0:36 4 May '07  
Thank you very much for your message. Indeed, I have neglected the AutoResetEvent (I hate it, by the way, because I had a project that almost failed due to my poor understanding of this guy!).

I've just tried the procedure that you recommend. It hangs. In fact, come to think of it, I see no reason why it _should not_ hang. It is the Post message that somehow does not get processed, I believe. So the function that runs on the GUI thread is not even called - the AutoResetEvent never gets to be set.

This seems to be the bug in the .NET 1.1 algorithm for Invoke/BeginInvoke, bug that fires when there are at least two processors; no workaround seems to work, so maybe we should call Microsoft for the fix...

[
Here is what I have: The GUI has a few panels with visual content (mainly SVG). They are updated quite often - 10 times per second or so - by some data which is computed in another process and passed here through .NET remoting. My code looks like:

protected delegate void DispatchNewValuesDelegate(Object o);
AutoResetEvent updateEvent;

public void DispatchNewValues(Object o)
{
if (this.InvokeRequired)
{
DispatchNewValuesDelegate delg = new DispatchNewValuesDelegate(dispatchNewValues);
IAsyncResult res = this.BeginInvoke(delg, new object[]{o});

updateEvent = new AutoResetEvent(false);
updateEvent.WaitOne();

// res.AsyncWaitHandle.WaitOne(30, true); // this is what I decided to use,
// although it may happen
// that from time to time it does not get updated
//// this.EndInvoke(res);
}
else {
dispatchNewValues(o);
}
}

private void dispatchNewValues(Object o)
{
// // do the job
// if (updateEvent!=null)
updateEvent.Set();
}

When it hangs, it is at updateEvent.WaitOne().
]
GeneralRe: Hanging BeginInvoke as well...
S. Senthil Kumar
8:13 4 May '07  
Petru66 wrote:
DispatchNewValuesDelegate delg = new DispatchNewValuesDelegate(dispatchNewValues);
IAsyncResult res = this.BeginInvoke(delg, new object[]{o});

updateEvent = new AutoResetEvent(false);

There lies your problem. You are creating a new AutoResetEvent after calling BeginInvoke, which means that if the UI thread got to run first, it will see that updateEvent is null and skip the Set method call. Moving the creation of the AutoResetEvent before the call to BeginInvoke should work.

DispatchNewValuesDelegate delg = new DispatchNewValuesDelegate(dispatchNewValues);
updateEvent = new AutoResetEvent(false);

IAsyncResult res = this.BeginInvoke(delg, new object[]{o});


In the problem I discovered, it was not that the posted messages did not run, it did - only that it did not signal the calling thread properly, which would make the calling thread hang if it waited for the signal.

Hope this helps.

Regards
Senthil [MVP - Visual C#]
_____________________________
My Blog | My Articles | My Flickr | WinMacro

Generalcan any one solve this
khurram1122
0:53 3 May '07  
scenario:
grab packets from network continuously
make them meaningful
write meaningful information to file

Problem:
packets are being captured on the main thread. asynchronous call BeginInvoke is used to write to file. i want that the thread created for first biginInvoke is used for entire write operations i.e i do not want to create threads by calling beginInvoke for every packet
any suggestion how to queue work for first thread created on calling BeginInvoke.Mad

Generalhelp please
dark_magician_6
8:09 27 Mar '07  
where could i get a sample of this project, because I'm new in C# and I'm interested in internet communication's. my e-mail is jurko007@gmail.com or d_magician_6@masn.com
Questionforce sendmessage
supmagc
23:41 13 Sep '06  
HI,

I'm currently working on some code: (executed on a asynchronously called thread)
public delegate void sendAnswer (RequestAnswer answer);

public event sendAnswer onSucces;

public RequestAnswer(Request request, WebResponse response, sendAnswer sender)
{
this.request = request;
this.response = response; // webresponse retrieved after webrequest.endGetResponse()
this.onSucces += sender; // add the sender-delegate to the event
// start reading the webResponse into one string
StreamReader reader = new StreamReader(this.response.GetResponseStream());
StringBuilder sb = new StringBuilder();
string line;
while ((line = reader.ReadLine()) != null)
{
sb.Append(line);
}
reader.Close();

// perform action on retrieved string
data = getData(sb.ToString());

// OPTIONAL MESSAGEBOX
MessageBox.Show(data);

// fire callback event
this.onSucces(this);
}

As you can see at the code, I'm trying to store data (retrieved by a webrequest) into a stringbuilder wich I eventualy flush into a string to perform some actions on.

Normally after my code ends, it than calls the sender method (specified in the constructor signature).

My problem is that without the optional messagebox, onSucces is fired before the data-field is set.

anyone knows what to do ?
AnswerRe: force sendmessage
S. Senthil Kumar
20:25 18 Sep '06  
supmagc wrote:
onSucces is fired before the data-field is set.

What exactly does that mean?

Regards
Senthil
_____________________________
My Blog | My Articles | WinMacro

GeneralThanks
Cap'n Al
5:31 1 Sep '06  
Nice article!
Generalrun waiting form in the front
roey frid
6:28 14 Aug '06  
i am a c# .net 2 programmer
i have a function that take a lot of time.
i want to show a waiting form until the function end.
how do i do it?

thanks and have a good day
GeneralRe: run waiting form in the front
Felipe Amorim
11:26 23 Aug '06  
Try searching for the BackgroundWorker Component. It'll do the trick.


Last Updated 3 Aug 2006 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010