-3

Suppose I have the following basic code in a WindowsFormsApplication.

ButtonClick(object sender, System.EventArgs e)
{
    Stopwatch SW = new Stopwatch();
    SW.Start();
    WriteToGui("Hello World");
    textBox1.Text += String.Format("Updated in {0} ms.{1}",
        SW.Elapsed.TotalMilliseconds,
        System.Environment.NewLine);
}

WriteToTheGUI(string newMessage)
{
     textBox1.Text += String.Format("{0}{1}", newMessage, System.Environment.NewLine);
}

I would get a textbox that looks like this:

Hello World
Updated in 0.5000 ms

I would like the output to actually be:

Updated in 0.0005 ms
Hello World

Edit: Took out all previous extra information.

The textbox control itself does have a message pump that can be invoked with BeginInvoke.

How can I replace the test update portion of the provided call with a call that would add the update to the textbox message pump and only handle it later?

Edit 3: There is too much focus on the UI itself and not the task at hand so I will try explaining the goal.

I have an external thrid party database logging and processing some specialized messaging.

I noticed that the basic send message command takes about .5 ms, I believe that it waits for a reply from the sever that it received the message. The underlying messages happen in bursts so I can have thousands of them or more to log very quickly. As a result the code can become extremely backed up. The messages look like this by time:

[        ][        ][        ][       ][       ]  and so on and the time keeps growing with more messages.

Each of the brackets represents the time to return from each message call. I want it to be:

[        ]
  [        ]
    [        ]   and so on so I am done with them quickly and waiting for replies.

The software and database can (supposedly) handle the much higher message rate that I am trying to achieve. Either way I will do all I can as fast as I can and wait. The software requires that any updates be sent from the thread that created the connection or use BeginInvoke to properly send the message. That is why I gave the UI as an example.

I do not need to wait for any responses or errors from the database as that is handled separately, I just need to send the messages as fast as possible and wait for replies.

I can see 2 ways of doing that, for every message, create a new thread for every message which will leave me with either thousands of thread or use a thread pool with limited threads which would again be slow as eventually it will sit and wait before sending more messages.

But I don't see any need to create and endless number of threads. I should be able to use BeginInvoke to add the message to the message pump, even though I don't need to. The stupid part is that I don't know how to do it when on the same thread. I just need the syntax for a forced BeginInvoke for any function method. Then I am free to do what I like and am only limited by the speed the message pump is handled.

Update:

Looking at the post here: How to update the GUI from another thread in C#? Changing the line in WriteToGUI to:

 textBox1.BeginInvoke(new Action(() => textBox1.Text += String.Format("{0}{1}", newMessage, System.Environment.NewLine)));

Actual output before:

Hello World
Updated in .2783 ms.

and after:

Updated in 0.0494 ms.
Hello World

this gives the desired result of returning immediately and printing "Hello World" after the time. However, does the Action in the example start a new thread or is this the best method to queue a new operation?

Community
  • 1
  • 1
Michael Elkin
  • 221
  • 2
  • 4
  • 15
  • Your entire question is pretty badly worded. You need to extract the long-running operation (whatever it is), put it onto its own thread and then call `BeginInvoke()` to call the UI to update. – xxbbcc Oct 13 '14 at 17:57
  • As in the question and in other cases, the long running operation is a single line, not an entire method. That is why I gave updating the UI as an example. Thank you. – Michael Elkin Oct 13 '14 at 18:08

1 Answers1

0

Half a millisecond is a really, really short period of time, on a human timescale. It's not like it's talking half a second or anything like that.

You can't update a textbox's text from another thread. You can only do that from the UI thread.

If you had a long running non-UI operation (currently you have very fast UI operation) then you can sensibly consider looking into alternatives.

Servy
  • 202,030
  • 26
  • 332
  • 449
  • On a human time scale yes, but for a computer it is an eternity. I though a textbook or control can be updated outside the thread using the Control.BeginInvoke approach. Yes it still executes the code on the UI thread, but it does it at some time later which is what I am trying to do. – Michael Elkin Oct 13 '14 at 18:10
  • @MichaelElkin You shouldn't be doing computational work in the UI thread to begin with. If you actually have long running non-UI work to do then it shouldn't be done in the UI thread, and so shouldn't be waiting on this; it should be done in another thread. – Servy Oct 13 '14 at 18:20
  • Thank you, but I want to clarify the UI is just an example. I am looking for a generic way to run single slow command (that must be run on the same thread) in a asynchronous way, meaning I don't wait for the result and can continue. – Michael Elkin Oct 13 '14 at 19:51
  • @MichaelElkin It's impossible in the general case. A lot of work needs to be put in place for a thread to be able to schedule operations to be executed on that thread; it needs a message pump, or some analogous concept. – Servy Oct 13 '14 at 19:53
  • Yes exactly, but how can I post a message to the message pump of a GUI control when I can update it directly? Every example I have seen involves different threads and I just cannot get it working. – Michael Elkin Oct 13 '14 at 20:28
  • 1
    @MichaelElkin What possible reason would you have for doing so here? If the UI operation is preventing some non-UI code from being run then that other code should be run in another thread. What possible reason do you have for *not* executing the UI operation immediately? – Servy Oct 13 '14 at 20:33