Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing object from backgroundworker to main thread

I have a WPF application that executes external programs to process media files, and so that the GUI doesn't freeze when the media files are being processed, I execute the process on a separate thread through backgroundworker.

        private void BackgroundWorkerExecProcess(Process process)
    {
        BackgroundWorker worker = new BackgroundWorker();
        worker.WorkerReportsProgress = false;
        worker.DoWork += DoWork;
        worker.RunWorkerCompleted += WorkerCompleted;
        worker.RunWorkerAsync(process);
    }
    void DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;
        Process process = e.Argument as Process;
        process.Start();
        string stderr = process.StandardError.ReadToEnd();
        //I want to display stderr on main thread
        process.WaitForExit();
    }
    void WorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        //some code to update gui telling user that process has finished
    }

so, if there is something printed to stderr, I can see it in the debugger, but if I try to do anything with the string stderr, such as if I have a textbox called "_tbLog" and did

_tbLog.Text+=stderr;    

I get an error from the compiler about them being on separate threads. is there a way to pass the object from the worker thread to the main thread?

like image 330
Jeff Crowell Avatar asked Dec 13 '22 11:12

Jeff Crowell


1 Answers

In DoWork, set e.Result to your object. In the WorkerCompleted you can get that object back out... it will once again be e.Result of type object. Just cast it to the object it was. The WorkerCompleted should be on the correct thread.

Here is one of mine:

private void workerUpdateBuildHistory_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    UpdateStatusModel model = (UpdateStatusModel)e.Argument;
    BuildService buildService = new BuildService(model.TFSUrl);
    e.Result = buildService.UpdateBuildHistoryList(model);
}

private void workerUpdateBuildHistory_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
    BuildHistoryListModel model = (BuildHistoryListModel)e.Result;
    if (model != null)
    {
        listViewPastBuilds.Items.Clear();
        foreach (var item in model.Builds)
        {
            listViewPastBuilds.Items.Add(item);
        }
    }
}
like image 161
CrazyDart Avatar answered Dec 27 '22 01:12

CrazyDart