Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>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.</p> <p>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</p> <p>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.</p> <pre><code>public class Program { private volatile bool AbortOperation; Func&lt;bool&gt; 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 = () =&gt; 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&lt;bool&gt; AbortOperation { get; set;} public Converter(Func&lt;bool&gt; 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); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload