Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Background worker, and cross thread issue

I have a Winforms application which is working fine.. using a BackgroundWorkerThread to manage GUI usability during processing of serial data to a device.

It's working fine.

Now, I am adding a new method, and copying what I did in other forms. But I am getting a cross thread exception.

I declare my BWT like this:

BackgroundWorker bw = new BackgroundWorker();
            bw.WorkerSupportsCancellation = true;
            bw.DoWork += DownloadGpsDataFromDevice;
            bw.WorkerReportsProgress = true;
            bw.RunWorkerAsync();

I then have a method delared like this, which does the background work:

private void DownloadGpsDataFromDevice(object sender, DoWorkEventArgs e)
{
    _performScreenUpdate = true;
    tsStatus.Text = "Downloading GPS Data...";
    Invalidate();
    Refresh();


    Common.WriteLog("Extracting raw GPS data. Sending LL.");

    ReplyString raw = DeviceServices.ExecuteCommand("$LL");

The DeviceServices.ExecuteCommand("$LL"); is the bit that does the work, but I am getting the exception on the previous line, where I log to a text file. Now, that makes you worry - writing to a file. However, I have done this thousands of times in another BWT.

I made the writing thread safe. Here this my Common.WriteLog method:

public static void WriteLog(string input)
{
    lock (_lockObject)
    {
        WriteLogThreadSafe(input);
    }
}

private static void WriteLogThreadSafe(string input)
{
    Directory.CreateDirectory(LogFilePath);
    StreamWriter w = File.AppendText(LogFilePath + @"\" + LogFileName);
    try
    {
        w.WriteLine(string.Format("{0}\t{1}", DateTime.Now, input));
    }
    catch (Exception e)
    {
        System.Console.WriteLine("Error writing to log file!");
        System.Console.WriteLine("Tried to write: [" + input + "]");
        System.Console.WriteLine("Failed with error: [" + e.Message + "]");
    }
    finally
    {
        w.Close();
    }

}

This have been working for ages. I don't believe the error is there. I think I am just missing something on the call maybe?

like image 591
Craig Avatar asked Dec 09 '25 20:12

Craig


1 Answers

You cannot change UI elements from BackgroundWorker thread. You'll have to marshall back to UI thread by calling Invoke().

Try this

private void DownloadGpsDataFromDevice(object sender, DoWorkEventArgs e)
{
    _performScreenUpdate = true;
    Invoke((MethodInvoker)(() => {
             tsStatus.Text = "Downloading GPS Data...";
             Invalidate();
             Refresh();
     });
     ...
like image 65
Bala R Avatar answered Dec 12 '25 09:12

Bala R



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!