Search code examples
c#wpfbackgroundworker

WPF UI update from BackgroundWorker


tried to find something similar but couldn't find.

i have a class that handles website ping (keep alive). this process runs in the background with a trigger of ON/OFF.

while the "Pinger" is running it should update the WPF TextBox with data such as: 1. loading start time 2. loading finish time 3. content length and some more information.

i am unable to access the TextBox from the Background worker as the TextBox is not static. when i send the TextBox as a parameter and update it from there i get receive an error which i cannot update the TextBox because it is running on another thread.

the main problem is that the BackgroundWorker runs CONSTANTLY asynchronously until it being shutdown manualy.

i tried the Dispacher, also tried to send the TextBox as Control as argument and edit from there.

here is a snippet for my Pinger class. thanks.

    class Pinger
{
    string urlToPing;
    int interval;
    BackgroundWorker bw;

    public Pinger()
    {
        urlToPing = Application.Current.Resources["UpdateUrl"].ToString();
        interval = int.Parse(Application.Current.Resources["RefreshRate"].ToString());

        bw = new BackgroundWorker();
        bw.WorkerReportsProgress = true;
        bw.WorkerSupportsCancellation = true;
        bw.DoWork += new DoWorkEventHandler(bw_DoWork);

    }

    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        PingIt();
        while (true)
        {
            if (bw.CancellationPending)
            {
                e.Cancel = true;
                break;
            }
            else
            {
                Thread.Sleep(interval * 1000);
                PingIt();
            }
        }
    }

    private void PingIt()
    {
        WebRequest req = HttpWebRequest.Create(urlToPing);
        WebResponse response = req.GetResponse();
    }
    public void Start(Control lastUpdateC, Control timeTakenC)
    {
        bw.RunWorkerAsync();
    }
    public void ShutDown() {
        bw.CancelAsync();
    }
}

Solution

  • You need to use the Background worker's Report Progress function. That marshals the call across from the background thread to the UI thread.

    Something like this - just change console to a text box.

    bw.ProgressChanged += (sender, eventArgs) =>
                {
                    Console.WriteLine(eventArgs.UserState);
                };
    
    
    private static void BwOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs)
            {
                var bw = sender as BackgroundWorker;
                bw.ReportProgress(0, "My State is updated");
            }