Click here to Skip to main content
15,908,013 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a button click that runs a lot of code. I would like to updata my UI while that code is running. It updates after the return from the button click. Can I display messages while in the button click?

Old guy.
Posted

You need to execute this code in some separate thread, not in your UI thread. But now…

You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

[EDIT]

And these are my answers on how to get and encapsulate a thread in a very robust way:
How to pass ref parameter to the thread[^],
change paramters of thread (producer) after it started[^],
MultiThreading in C#[^].

[EDIT]

A big warning: Many advise to use Application.DoEvent instead of thread. Don't do it. To certain extent, it can work, but better stay out of trouble and waste of your time. Too long to explain…

—SA
 
Share this answer
 
v3
Comments
Garth J Lancaster 11-Jan-13 18:59pm    
nice reply Sergey !
Sergey Alexandrovich Kryukov 11-Jan-13 19:03pm    
Thank you very much, Garth. Did you mean to vote then? :-)
—SA
Garth J Lancaster 11-Jan-13 19:08pm    
my bad - sorry, I was reading through all the references you had provided - I dont do a lot of forms type work - services or console mode apps yes, but sooner or later I'll come across the need for a forms app (I come from a messaging type bacground, so the approach is logical, just the actual mechanics Im short on)
Sergey Alexandrovich Kryukov 11-Jan-13 20:03pm    
Absolutely nothing to apologize for. You are absolutely not obliged to give any certain feedback. And thank you.
—SA
Garth J Lancaster 11-Jan-13 19:09pm    
I've gone back and '5' voted it :-)
Hello,


You should try using the backgroundworker class to do this.

Setup a DoWork event handler and put in it the long code that your button is doing. In your code instead of updating the UI just raise an event ReportProgress and pass the data needed to update this UI.

Setup a ProgressChanged event handler. This is this event that will receive notifications from the background worker thread and in which you can safely update the UI.


Here is an example:

C#
public Form1()
{
    InitializeComponent();
    backWkr.WorkerReportsProgress = true;
    backWkr.ProgressChanged += backWkr_ProgressChanged;
    backWkr.DoWork += backWkr_DoWork;
}

BackgroundWorker backWkr = new BackgroundWorker();

private void button1_Click(object sender, EventArgs e)
{
    backWkr.RunWorkerAsync();
}

void backWkr_DoWork(object sender, DoWorkEventArgs e)
{
    // the code that take tsome time to execute.
    int percentProgress = 0;
    do
    {
        percentProgress++;
        // simulate some long operation...
        Thread.Sleep(100);
        object whatEverIsNeeded = "blah blah blah";
        backWkr.ReportProgress(percentProgress, whatEverIsNeeded);
    } while (percentProgress < 100 );
}

void backWkr_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // get the data...
    object whatEverStatepassed = e.UserState;
    int percent = e.ProgressPercentage;
    // update ui, do something... eyc...
    this.BackColor = Color.FromArgb(this.BackColor.R, this.BackColor.G, percent);
}


Valery.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900