Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 193697
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 11, 20262026-05-11T16:31:56+00:00 2026-05-11T16:31:56+00:00

I have just stumbled across the Backgroundworker object, and it seems like the tool

  • 0

I have just stumbled across the Backgroundworker object, and it seems like the tool I’m looking for to make my GUI responding while performing calculations. I am writing IO plugins for ArcGIS.

I am doing some data processing outside ArcGIS, which works fine using the backgroundworker. But when I’m inserting the data into ArcGIS, the backgroundworker seems to increase the duration time by a factor 9 or so. Placing the processing code outside the DoWork method, increases the performance by a factor 9.

I have read about this several places on the net, but I have no experience in multithreaded programming and the terms like STA and MTA means nothing to me. link text
I have also tried to use a simple implementation of threading, but with similar results.

Does anyone know what I can do to be able to use ArcGIS processing and maintaining a responsive GUI?

EDIT: I have included a sample of my interaction with the background worker. If I put the code located in the StartImporting method in the cmdStart_Click method, it executes much faster.

private void StartImporting(object sender, DoWorkEventArgs e)
{
    DateTime BeginTime = DateTime.Now;
    // Create a new report object.
    SKLoggingObject loggingObject = new SKLoggingObject("log.txt");
    loggingObject.Start("Testing.");

    SKImport skImporter = new SKImport(loggingObject);
    try
    {
        // Read from a text box - no writing.
    skImporter.Open(txtInputFile.Text);
    }
    catch
    {
    }
    SKGeometryCollection convertedCollection = null;

    // Create a converter object.
    GEN_SK2ArcGIS converter = new GEN_SK2ArcGIS(loggingObject);

    // Convert the data.
    convertedCollection = converter.Convert(skImporter.GetGeometry());

    // Create a new exporter.
    ArcGISExport arcgisExporter = new ArcGISExport(loggingObject);

    // Open the file.            
    // Read from a text box - no writing.
    arcgisExporter.Open(txtOutputFile.Text);

    // Insert the geometry collection.
    try
    {
    arcgisExporter.Insert(convertedCollection);
    }
    catch
    {
    }
    TimeSpan totalTime = DateTime.Now - BeginTime;
    lblStatus.Text = "Done...";

}

private void ChangeProgress(object sender, ProgressChangedEventArgs e) 
{
    // If any message was passed, display it.
    if (e.UserState != null && !((string)e.UserState).Equals(""))
    {
    lblStatus.Text = (string)e.UserState;
    }
    // Update the progress bar.
    pgStatus.Value = e.ProgressPercentage;
}

private void ImportDone(object sender, RunWorkerCompletedEventArgs e)
{
    // If the process was cancelled, note this.
    if (e.Cancelled)
    {
    pgStatus.Value = 0;
    lblStatus.Text = "Operation was aborted by user...";
    }
    else
    {
    }

}

private void cmdStart_Click(object sender, EventArgs e)
{
    // Begin importing the sk file to the geometry collection.

    // Initialise worker.
    bgWorker = new BackgroundWorker();
    bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ImportDone);
    bgWorker.ProgressChanged += new ProgressChangedEventHandler(ChangeProgress);
    bgWorker.DoWork += new DoWorkEventHandler(StartImporting);
    bgWorker.WorkerReportsProgress = true;
    bgWorker.WorkerSupportsCancellation = true;

    // Start worker.
    bgWorker.RunWorkerAsync();

}

private void cmdCancel_Click(object sender, EventArgs e)
{
    bgWorker.CancelAsync();
}

Kind Regards, Casper

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-11T16:31:57+00:00Added an answer on May 11, 2026 at 4:31 pm

    I have continued trying to find a solution, and the following is what I ended up doing. The code is cut and paste from various files and presented to give an idea of what I did. It demonstrates how I can call methods which are communicating with ArcGIS using a thread. The code allows me to update the GUI in the main thread, abort the operation, and do post-operation stuff. I ended up using the first threading part from the link I posted initially.

    The reason for the initial loss of performance is probably due to the single-threaded apartment (STA) which is required by ArcGIS. The Backgroundworker seems to be MTA, thus not appropriate for working with ArcGIS

    Well here it goes, I hope I haven’t forgotten anything, and feel very free to edit my solution. It will both help me and probably also other people developing stuff for ArcGIS.

    public class Program
    {
        private volatile bool AbortOperation;
        Func<bool> AbortOperationDelegate;
        FinishProcessDelegate finishDelegate;
        UpdateGUIDelegate updateGUIDelegate;
    
        private delegate void UpdateGUIDelegate(int progress, object message);
        private delegate void FinishProcessDelegate();
    
        private void cmdBegin_Click(...)
        {
            // Create finish delegate, for determining when the thread is done.
            finishDelegate = new FinishProcessDelegate(ProcessFinished);
            // A delegate for updating the GUI.
            updateGUIDelegate = new UpdateGUIDelegate(UpdateGUI);
            // Create a delegate function for abortion.
            AbortOperationDelegate = () => AbortOperation;
    
            Thread BackgroundThread = new Thread(new ThreadStart(StartProcess));            
            // Force single apartment state. Required by ArcGIS.
            BackgroundThread.SetApartmentState(ApartmentState.STA);
            BackgroundThread.Start();
        }
    
        private void StartProcess()
        {    
            // Update GUI.
            updateGUIDelegate(0, "Beginning process...");
    
            // Create object.
            Converter converter = new Converter(AbortOperationDelegate);
            // Parse the GUI update method to the converter, so it can update the GUI from within the converter. 
            converter.Progress += new ProcessEventHandler(UpdateGUI);
            // Begin converting.
            converter.Execute();
    
            // Tell the main thread, that the process has finished.
            FinishProcessDelegate finishDelegate = new FinishProcessDelegate(ProcessFinished);
            Invoke(finishDelegate);
    
            // Update GUI.
            updateGUIDelegate(100, "Process has finished.");
        }
    
        private void cmdAbort_Click(...)
        {
            AbortOperation = true;
        }
    
        private void ProcessFinished()
        {
            // Post processing.
        }
    
        private void UpdateGUI(int progress, object message)
        {
            // If the call has been placed at the local thread, call it on the main thread.
            if (this.pgStatus.InvokeRequired)
            {
                UpdateGUIDelegate guidelegate = new UpdateGUIDelegate(UpdateGUI);
                this.Invoke(guidelegate, new object[] { progress, message });
            }
            else
            {
                // The call was made on the main thread, update the GUI.
                pgStatus.Value = progress;
                lblStatus.Text = (string)message;   
            }
        }
    }
    
    public class Converter
    {
        private Func<bool> AbortOperation { get; set;}
    
        public Converter(Func<bool> abortOperation)
        {
            AbortOperation = abortOperation;
        }
    
        public void Execute()
        {
            // Calculations using ArcGIS are done here.
            while(...) // Insert your own criteria here.
            {
                // Update GUI, and replace the '...' with the progress.
                OnProgressChange(new ProgressEventArgs(..., "Still working..."));
    
                // Check for abortion at anytime here...
                if(AbortOperation)
                {
                    return;
                }
            }
        }
    
        public event ProgressEventHandler Progress;
        private virtual void OnProgressChange(ProgressEventArgs e)
        {
            var p = Progress;
            if (p != null)
            {
                // Invoke the delegate. 
            p(e.Progress, e.Message);
            }
        }    
    }
    
    public class ProgressEventArgs : EventArgs
    {
        public int Progress { get; set; }
        public string Message { get; set; }
        public ProgressEventArgs(int _progress, string _message)
        {
            Progress = _progress;
            Message = _message;
        }
    }
    
    public delegate void ProgressEventHandler(int percentProgress, object userState);
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

No related questions found

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.