Author Topic: BackgroundWorker & ShowModalDialog  (Read 17250 times)

0 Members and 1 Guest are viewing this topic.

Bobby C. Jones

  • Swamp Rat
  • Posts: 516
  • Cry havoc and let loose the dogs of war.
BackgroundWorker & ShowModalDialog
« on: March 01, 2009, 07:33:31 PM »
From a UserControl on a palette, I start a background worker that when complete opens a drawing.  All is well until I launch a modal dialog from the palette.  After closing the modal dialog the next call to the background worker causes a fatal error and kills acad.  Any thoughts?  Thanks.

Code: [Select]
  public partial class UserControl1 : UserControl
  {
    public UserControl1()
    {
      InitializeComponent();
    }

    private void ShowModalFormButton_Click(object sender, EventArgs e)
    {
      Form1 modalForm = new Form1();

      acadApp.ShowModalDialog(modalForm);
    }

    private void OpenDrawingButton_Click(object sender, EventArgs e)
    {
      BackgroundWorker worker = new BackgroundWorker();
      worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
      worker.DoWork += new DoWorkEventHandler(worker_DoWork);
      worker.RunWorkerAsync();
    }

    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
      //Long running process
    }

    void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
      //Long running process is complete.
      acadApp.DocumentManager.Open(@"C:\OftenUsedBlock.dwg", false);
    }
  }
Bobby C. Jones

Chuck Gabriel

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #1 on: March 02, 2009, 08:28:04 AM »
I wish I had some useful advice for you Bobby, but about the most intelligent-sounding thing I can come up with is maybe you have a deadlock.  Wouldn't that just hang the application though?

Draftek

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #2 on: March 02, 2009, 09:04:45 AM »
I don't believe the AutoCAD application supports multi-threading, does it?

I could be wrong but I usually save any threading to non-autocad related activities like showing a progress bar duing a long process, etc.

I could be wrong - don't tell my wife, though.

Bobby C. Jones

  • Swamp Rat
  • Posts: 516
  • Cry havoc and let loose the dogs of war.
Re: BackgroundWorker & ShowModalDialog
« Reply #3 on: March 02, 2009, 09:47:14 AM »
I don't believe the AutoCAD application supports multi-threading, does it?

I could be wrong but I usually save any threading to non-autocad related activities like showing a progress bar duing a long process, etc.

I could be wrong - don't tell my wife, though.

You are correct, you cannot interact with autocad on multiple threads.  And I didn't think that I was.  However, your post got me to thinking.  I modified the RunWorkerCompleted callback like so:

Code: [Select]
    void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
      //Long running process is complete.
      acadApp.ShowAlertDialog(this.InvokeRequired.ToString());
    }

This returns False until after the modal dialog is shown.  I'm sure there's a fundamental aspect of threading that I just don't grasp and this really does makes sense.  Maybe someone can help me to understand; I'm all ears.  In the meantime I'm going to test for InvokeRequired and invoke the call on the main thread as needed.
Bobby C. Jones

tjr

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #4 on: March 02, 2009, 10:41:26 AM »
I used BackgroundWorker quite a bit in a BOM app I created and I never had any luck running it from anything other than inside a windows form. From there I would do something like:

Code: [Select]
Form1 modalForm = new Form1();
if (modelForm.ShowDialog() == DialogResult.Ok)
{
   acadApp.DocumentManager.Open(modelForm.MyPublicStringThatContainsADrawingName, false);
}

When ShowDialog was called it would do all the BackgroundWorker stuff and I would then pass the results back in some form of public property.

Not sure if this answers your question or not, but this is the experience I had.

Draftek

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #5 on: March 02, 2009, 11:10:57 AM »
Here is what I've done - use a while (backgroundworker.IsBusy) loop and then open the drawing outside of the thread, instead of in the workcompleted event.

ReneRam

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #6 on: March 02, 2009, 11:23:59 AM »
 :|
Sorry, it's not relevant to this post, but I've been going through an issue like this, ModalFormDialog and opening a drawing a drawing while the form is open. I asked help to the ADN and it partially helped, I'm still working on the thing, but as long as I have understood until now it all involves the current editor when the dialog is shown.
I have moved part of my code from the form to the Commands module and launch it with a SendStringToExecute("OpenDrawing ", True, False, False) and the CommandMethod for the OpenDrawing with no CommandFlags.
As I said I'm still working on it, but the flags ".InProgress", "Transparent" and "Session" give different results, also AutoCAD crashing. I'm still testing and I'm looking for a good explanation of the exact meaning of the flags.

Bobby C. Jones

  • Swamp Rat
  • Posts: 516
  • Cry havoc and let loose the dogs of war.
Re: BackgroundWorker & ShowModalDialog
« Reply #7 on: March 02, 2009, 11:44:43 AM »
Hey Dt,
Doesn't that defeat the purpose of using a BackgroundWorker?  I need to capture progress and provide the ability to cancel the worker.

Here is what I've done - use a while (backgroundworker.IsBusy) loop and then open the drawing outside of the thread, instead of in the workcompleted event.
Bobby C. Jones

Bobby C. Jones

  • Swamp Rat
  • Posts: 516
  • Cry havoc and let loose the dogs of war.
Re: BackgroundWorker & ShowModalDialog
« Reply #8 on: March 02, 2009, 11:47:41 AM »
I've never tried to open a drawing from a modal form, which I would think goes against the purpose of a modal form anyway.  Sorry I couldn't be of more help.

:|
Sorry, it's not relevant to this post, but I've been going through an issue like this, ModalFormDialog and opening a drawing a drawing while the form is open. I asked help to the ADN and it partially helped, I'm still working on the thing, but as long as I have understood until now it all involves the current editor when the dialog is shown.
I have moved part of my code from the form to the Commands module and launch it with a SendStringToExecute("OpenDrawing ", True, False, False) and the CommandMethod for the OpenDrawing with no CommandFlags.
As I said I'm still working on it, but the flags ".InProgress", "Transparent" and "Session" give different results, also AutoCAD crashing. I'm still testing and I'm looking for a good explanation of the exact meaning of the flags.

Bobby C. Jones

Draftek

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #9 on: March 02, 2009, 12:28:25 PM »
Here is how I see it:

Your modal dialog is running inside the current application thread. as in - acadApp.ShowModalDialog()
You CANNOT do anything AutoCAD application specific (Like opening a drawing) inside another thread (your background worker).

Bobby C. Jones

  • Swamp Rat
  • Posts: 516
  • Cry havoc and let loose the dogs of war.
Re: BackgroundWorker & ShowModalDialog
« Reply #10 on: March 02, 2009, 02:01:21 PM »
I think that due to my poor explanation there's some confusion.  I'm not interacting with AutoCAD from the Modal Dialog; I'm only collecting info from the user.  In the example that I put together for this post, the modal form doesn't even have any controls on it.

I can press the Open Drawing button all day long and it will open the file.  But, if I press the button to display the modal dialog and then close that dialog, the next time I press the button to open the drawing, BOOM!

After my last findings I know what's going on, but I don't know why.  This project is sittin' until I git my edumication finsihed on these thread things.

Here is how I see it:

Your modal dialog is running inside the current application thread. as in - acadApp.ShowModalDialog()
You CANNOT do anything AutoCAD application specific (Like opening a drawing) inside another thread (your background worker).

Bobby C. Jones

Draftek

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #11 on: March 02, 2009, 03:51:14 PM »
I see, but it's still the same problem, just in reverse.

This is your problem:
Code: [Select]
   void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
      //Long running process is complete.
      acadApp.DocumentManager.Open(@"C:\OftenUsedBlock.dwg", false);
    }

Instead of opening the drawing here, have the background worker report back to the client (openDrawingButton_Click event) whether it was successful or not using a while loop to make sure the background worker is not busy as in:
while (myBackgroundworker.IsBusy)
{
application.DoEvents
}

Then if successful, open the drawing.

I re-created you code as above and clicked both buttons several times with no crashes..


 

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8661
  • AKA Daniel
Re: BackgroundWorker & ShowModalDialog
« Reply #12 on: March 02, 2009, 04:04:09 PM »
...  In the example that I put together for this post...


Can you post your sample solution so others might play? 

ReneRam

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #13 on: March 03, 2009, 04:58:01 AM »
Sorry Bobby, maybe I didn't explain myself well, I'm not suggesting a solution, I don't think I have the knowledge since I'm still trying to solve a similar issue, what I was trying to say is that maybe moving part of your code (the myBackgroundworker) to the Commands module and activating it with a CommandFlags like ".Transparent" could solve.
As much as I know I think, but I'm not sure, you can have only 1 Active Editor for each Session of AutoCAD, so when you you press the OpenDrawing, actually I think you are changing the Active Editor. The acadApp.ShowModalDialog() sort of "freezes" the current Editor until the dialog is open.
In my program I do something like this:

from the ModalDialog:
Code: [Select]
Public Sub MakeNewDWG()

 

        myForm.Hide()

        Application.DocumentManager.MdiActiveDocument.SendStringToExecute("MakeDoc ", True, False, True)

 

    End Sub


and from the Commands module:

Code: [Select]
    <CommandMethod("MakeDoc", CommandFlags.Session)> _

    Public Sub MakeDoc()

        Dim myDoc As ApplicationServices.Document

        myDoc = Application.DocumentManager.Add("c:\temp\myTemplate.dwt")

        myDoc.Database.SaveAs("c:\temp\myDwg.dwg", DatabaseServices.DwgVersion.Current)

        myDoc.CloseAndDiscard()

        myDoc = Application.DocumentManager.Open("c:\temp\myDwg.dwg", False)

    End Sub



This does not give any crash, I discovered that my problem was a matter of synchronization. When I exit the Dialog, even if I see my new drawing in the background, the Editor switches to the Editor that was opened when I launched the Dialog the first time.
If I change the CommandFlag, what I'm trying to do is actually change the current drawing in to the new one, so like in your case change the active Editor, I get different kind of results, even having my new drawing filled with the ents created by my code, but with No Editor accessible to the User when I exit the Code in the Dialog.

So as I said in my previous post, I'm not trying to give a solution, but just suggesting to explore the idea of moving the Backgroundworker in a command that works "Transparent" to the current session and having it change a public variable that you can check before anything else, in this way I think you have much more control on what's happening

Bobby C. Jones

  • Swamp Rat
  • Posts: 516
  • Cry havoc and let loose the dogs of war.
Re: BackgroundWorker & ShowModalDialog
« Reply #14 on: March 03, 2009, 03:27:00 PM »
Hey Daniel, I'll post it tonight.

...  In the example that I put together for this post...


Can you post your sample solution so others might play? 
Bobby C. Jones

Bobby C. Jones

  • Swamp Rat
  • Posts: 516
  • Cry havoc and let loose the dogs of war.
Re: BackgroundWorker & ShowModalDialog
« Reply #15 on: March 04, 2009, 10:05:26 AM »
This is a VS2008 project stripped down to bare bones.  When you load it the palette will display.  Press the open drawing button a few times and open several drawings.  All appears to be well.  Now press the open modal dialog button and close the dialog that shows.

The next time you press the open drawing button you'll get the crash.

I've commented out a couple of methods and a delegate that invoke the Open() call on the UI thread and this works, but because of my lack of understanding of what's really going on, I get a feeling that I'm just covering up a deeper issue that's going to come back and bite me in the a$$.  I'm putting this on hold until I gain a better understanding.

...  In the example that I put together for this post...


Can you post your sample solution so others might play? 
Bobby C. Jones

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8661
  • AKA Daniel
Re: BackgroundWorker & ShowModalDialog
« Reply #16 on: March 04, 2009, 11:57:31 PM »
interesting, have a look at this...

Quote
OnOpenDwgBtnClickThread 3
workerThread_DoWork 1
workerThread_RunWorkerCompleted 3
OnOpenDwgBtnClickThread 3
workerThread_DoWork 1
workerThread_RunWorkerCompleted 3
OnShowDialogBtnClick 3
OnShowDialogBtnClick 3
OnShowDialogBtnClick 3
OnOpenDwgBtnClickThread 3
workerThread_DoWork 1
workerThread_RunWorkerCompleted 1
OnOpenDwgBtnClickThread 3
workerThread_DoWork 1
workerThread_RunWorkerCompleted 1
OnOpenDwgBtnClickThread 3
workerThread_DoWork 1
workerThread_RunWorkerCompleted 1



Code: [Select]
using System;
using System.Threading;
using System.ComponentModel;
using System.Windows.Forms;
using System.IO;

using acadApp = Autodesk.AutoCAD.ApplicationServices.Application;
using acadFileDlg = Autodesk.AutoCAD.Windows.OpenFileDialog;


namespace ThreadingExample
{
  public partial class UserControl1 : UserControl
  {
    TextWriter writer;
    public UserControl1()
    {
      InitializeComponent();
      writer = StreamWriter.Synchronized(new StreamWriter(@"C:\Thread.txt", true));
    }

    ~UserControl1()
    {
      writer.Flush();
      writer.Close();
    }

    private string FileName { get; set; }

    private void OnOpenDwgBtnClick(object sender, EventArgs e)
    {
      writer.WriteLine(String.Format("OnOpenDwgBtnClickThread {0}",
        Thread.CurrentThread.ManagedThreadId));

      //Select a file to open
      acadFileDlg fileDlg = new acadFileDlg
        ("Theading Example", "", "DWG", "dialog name", acadFileDlg.OpenFileDialogFlags.ForceDefaultFolder);

      DialogResult result = fileDlg.ShowDialog();

      if (result != DialogResult.OK)
      {
        return;
      }

      //Store the file name
      this.FileName = fileDlg.Filename;

      //Launch a worker thread
      BackgroundWorker workerThread = new BackgroundWorker();
      workerThread.DoWork += new DoWorkEventHandler(workerThread_DoWork);
      workerThread.RunWorkerCompleted +=
        new RunWorkerCompletedEventHandler(workerThread_RunWorkerCompleted);
      workerThread.RunWorkerAsync();
    }

    private void workerThread_DoWork(object sender, DoWorkEventArgs e)
    {
      writer.WriteLine(String.Format
        ("workerThread_DoWork {0}", Thread.CurrentThread.ManagedThreadId));
      //Define background process here.  For this example I do no work on the background thread.
    }


    private void workerThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
      writer.WriteLine(String.Format
        ("workerThread_RunWorkerCompleted {0}", Thread.CurrentThread.ManagedThreadId));
      //The worker thread is complete and this call should be on the main thread, right?
      //if(e.Error == null)
      //acadApp.DocumentManager.Open(this.FileName, false);
    }


    #region Invoke acadApp.DocumentManager.Open()
    //private void workerThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    //{
    //  if (this.InvokeRequired)
    //  {
    //    this.Invoke(new OpenDrawingHandler(OpenDrawing), this.FileName, false);
    //  }
    //  else
    //  {
    //    acadApp.DocumentManager.Open(this.FileName, false);
    //  }
    //}

    //private delegate void OpenDrawingHandler(string fileName, bool openReadOnly);

    //private void OpenDrawing(string fileName, bool openReadOnly)
    //{
    //  acadApp.DocumentManager.Open(fileName, openReadOnly);
    //}
    #endregion


    private void OnShowDialogBtnClick(object sender, EventArgs e)
    {
      writer.WriteLine(String.Format
        ("OnShowDialogBtnClick {0}", Thread.CurrentThread.ManagedThreadId));
      Form1 modalForm = new Form1();
      acadApp.ShowModalDialog(modalForm);
    }
  }
}


It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8661
  • AKA Daniel
Re: BackgroundWorker & ShowModalDialog
« Reply #17 on: March 05, 2009, 12:08:39 AM »
The threads seem to change up after the modal form is shown, I’m not sure how to fix this though.

Quote
OnOpenDwgBtnClickThread 3
workerThread_DoWork 1
workerThread_RunWorkerCompleted 3
OnOpenDwgBtnClickThread 3
workerThread_DoWork 1
workerThread_RunWorkerCompleted 3
OnOpenDwgBtnClickThread 3
workerThread_DoWork 1
workerThread_RunWorkerCompleted 3
OnOpenDwgBtnClickThread 3
workerThread_DoWork 1
workerThread_RunWorkerCompleted 3
OnOpenDwgBtnClickThread 3
workerThread_DoWork 1
workerThread_RunWorkerCompleted 3
OnOpenDwgBtnClickThread 3
workerThread_DoWork 1
workerThread_RunWorkerCompleted 3
OnShowDialogBtnClick 3;------------------------------
OnOpenDwgBtnClickThread 3
workerThread_DoWork 1
workerThread_RunWorkerCompleted 1
OnOpenDwgBtnClickThread 3
workerThread_DoWork 1
workerThread_RunWorkerCompleted 1
OnOpenDwgBtnClickThread 3
workerThread_DoWork 1
workerThread_RunWorkerCompleted 1
OnOpenDwgBtnClickThread 3
workerThread_DoWork 1
workerThread_RunWorkerCompleted 1
OnOpenDwgBtnClickThread 3
workerThread_DoWork 1
workerThread_RunWorkerCompleted 1

Bobby C. Jones

  • Swamp Rat
  • Posts: 516
  • Cry havoc and let loose the dogs of war.
Re: BackgroundWorker & ShowModalDialog
« Reply #18 on: March 05, 2009, 10:19:01 AM »
The threads seem to change up after the modal form is shown, I’m not sure how to fix this though.

Well there it is in a visual format.  Thanks a lot for taking a look at this Daniel.  The call can be fixed by invoking it on the UI thread, but this leaves too many unknowns for me to be comfortable.
Bobby C. Jones

MikeTuersley

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #19 on: March 07, 2009, 04:49:38 PM »
A simple fix is to use Windows Show methods, not the AutoCAD.Application Show methods. Threading then is not an issue.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8661
  • AKA Daniel
Re: BackgroundWorker & ShowModalDialog
« Reply #20 on: March 07, 2009, 07:51:30 PM »
A simple fix is to use Windows Show methods, not the AutoCAD.Application Show methods. Threading then is not an issue.

I thought about this too as AutoCAD.Application Show methods have a little background mojo going on, but it didn’t make any difference

ps: Welcome to theSwamp!!

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: BackgroundWorker & ShowModalDialog
« Reply #21 on: March 07, 2009, 08:21:48 PM »
A simple fix is ......

Do you have a solution to demonstrate this Mike ?

Welcome to TheSwamp.
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

TonyT

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #22 on: March 07, 2009, 11:10:13 PM »
A simple fix is to use Windows Show methods, not the AutoCAD.Application Show methods. Threading then is not an issue.

Mike - Why is threading not an issue with the Form's Show()/ShowDialog() methods?

MikeTuersley

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #23 on: March 08, 2009, 10:28:43 AM »
Kerry - just substitute modalForm.Show(); for acadApp.ShowModalDialog(modalForm); in Bobby's example.

Tony - I've used threading for years without any problems. Granted, though, I have not used the BackGroundWorker object - I've always implemented standard threading. I tried Bobby's sample with the Windows' Show and ShowDialog and his problem disappears. It is possible that, at some low level, there could still be an issue but I've not run into it. It's possible that the problem is AutoCAD interacting with the BackGroundWorker - I didn't have time to swap in my standard thread implementation.

My suggestion of using Windows' functionality does have drawbacks per Kean's blog http://tinyurl.com/bakxjm :

Quote
There are a number of reasons to use Application.Show[Modal/Modeless]Dialog() rather than Form.Show[Dialog]:

1. Dialogs will automatically pick up the icon of the host product
2. Dialog size and position will be persisted automatically
3. Other floating AutoCAD windows (e.g. the Properties palette) will be disabled, as needed
4. The DIASTAT system variable will be set properly with the exit status of the dialog

Assuming you can live with the 4 items listed above, I don't see a reason not to use Windows' functionality.

TonyT

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #24 on: March 08, 2009, 06:05:11 PM »


Kerry - just substitute modalForm.Show(); for acadApp.ShowModalDialog(modalForm); in Bobby's example.


Mike - Sorry, but I think you seem to have
gotten modal and modeless confused.

Show() displays a form modelessly, not modally as
Application.ShowModalDialog() and Form.ShowDialog() does.

If what you are suggesting is that the way to solve the
problem is to use a modeless dialog rather than a modal
dialog, well, that's not really a solution at all.

Quote
Tony - I've used threading for years without any problems. Granted, though, I have not used the BackGroundWorker object - I've always implemented standard threading.

Mike - feel free to expand on how you've used threading for years without any problems.


MikeTuersley

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #25 on: March 09, 2009, 01:17:38 AM »
Glad to see some people never change, Tony!

Thank you, yes, I did make a mistake in replying too fast to Kerry. After testing out my recommendation, showing the form modally via the Application or Windows, still throws the error. To get around it, you could go really hokie:

- Take a screen cap of the AutoCAD window [see below]
- Size the dialog to the AutoCAD Window and position it over it
- Add the screen cap as the form's background image
- Use Show() instead of ShowModalDialog()
- Do the processing and close the form

Not pretty, but it works.

Code: [Select]
public static Image CaptureWindow(IntPtr handle)
{
    // get te hDC of the target window
    IntPtr hdcSrc = User32.GetWindowDC(handle);
    // get the size
    Win32.RECT windowRect = new Win32.RECT();
    User32.GetWindowRect(handle, windowRect);
    int width = windowRect.right - windowRect.left;
    int height = windowRect.bottom - windowRect.top;
    // create a device context to copy to
    IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
    // create a bitmap to copy it to,
    // using GetDeviceCaps to get the width/height
    IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
    // select the bitmap object
    IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
    // bitblt over
    GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
    // restore selection
    GDI32.SelectObject(hdcDest, hOld);
    // clean up
    GDI32.DeleteDC(hdcDest);
    User32.ReleaseDC(handle, hdcSrc);
     // get a .NET image object for it
    Image img = Image.FromHbitmap(hBitmap);
    // free up the Bitmap object
    GDI32.DeleteObject(hBitmap);
    return img;
}

MikeTuersley

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #26 on: March 09, 2009, 01:22:11 AM »
Oh! And threading? I have always used it with accont and then the toolpalette control. The threading never directly interacts with AutoCAD; it's always pulling in data from sql or an xml file to populate the controls on the dockable container.

Chuck Gabriel

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #27 on: March 09, 2009, 07:22:30 AM »
Not trying to change the subject or anything, but welcome to the swamp Mike.

MikeTuersley

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #28 on: March 09, 2009, 08:00:17 AM »
Hi Chuck! Thanks!

TonyT

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #29 on: March 09, 2009, 12:22:36 PM »
Glad to see some people never change, Tony!

Ditto.

Quote

Thank you, yes, I did make a mistake in replying too fast to Kerry. After testing out my recommendation, showing the form modally via the Application or Windows, still throws the error. To get around it, you could go really hokie:

- Take a screen cap of the AutoCAD window [see below]
- Size the dialog to the AutoCAD Window and position it over it
- Add the screen cap as the form's background image
- Use Show() instead of ShowModalDialog()
- Do the processing and close the form

Not pretty, but it works.


:lmao: 

Mike - No, I'm afraid that doesn't work, but thanks
for a good laugh.


MikeTuersley

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #30 on: March 09, 2009, 12:59:20 PM »
Well, I said it wasn't pretty but it does work. If the user tries to pick inside cad, they're just picking on the image. It all depends upon how badly and quickly the functionality is needed [try working for a VAR that can only sell fixed bid projects :)]. I'm sure there is a more eloquent and proper workaround.
« Last Edit: March 09, 2009, 02:10:12 PM by MikeTuersley »

Bobby C. Jones

  • Swamp Rat
  • Posts: 516
  • Cry havoc and let loose the dogs of war.
Re: BackgroundWorker & ShowModalDialog
« Reply #31 on: March 10, 2009, 09:09:35 AM »
Hey Mike.  It's good to hear from you.  I missed you at AU this year, although I did run into some of your old co-workers from that VAR :)  Thanks for the suggestions, and welcome to The Swamp.

After some further reading on the net, I think I'm on the right track by checking .InvokeRequired and calling .Invoke, or .BeginInvoke, as needed in the RunWorkerCompleted callback.  Although I am on the hunt for a good book on Windows threading; it was a bad assumption gleaned from an internet site on the BackgroundWorker component, coupled with my ignorance, that lead me to create this bug in the first place.

Well, I said it wasn't pretty but it does work. If the user tries to pick inside cad, they're just picking on the image. It all depends upon how badly and quickly the functionality is needed [try working for a VAR that can only sell fixed bid projects :)]. I'm sure there is a more eloquent and proper workaround.
« Last Edit: March 10, 2009, 10:58:12 AM by Bobby C. Jones »
Bobby C. Jones

MikeTuersley

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #32 on: March 10, 2009, 10:21:31 AM »
Hey Bobby! Nice to "see" you, too! I kept running into people @ AU telling me you were there but I never seemed to be able to track you down. Maybe this year  ;-)

TonyT

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #33 on: March 11, 2009, 05:27:49 PM »
Sorry, have to disagree.

It may work from your perspective if you hold a
myopic view of the problem, and perhaps because
you haven't even begun to consider how easily it
can be broken or how many things can go wrong.

So perhaps in your mind it works.

Realistlcally, it does not.


Well, I said it wasn't pretty but it does work. If the user tries to pick inside cad, they're just picking on the image. It all depends upon how badly and quickly the functionality is needed [try working for a VAR that can only sell fixed bid projects :)]. I'm sure there is a more eloquent and proper workaround.

MikeTuersley

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #34 on: March 11, 2009, 11:35:29 PM »
I totally agree with you - anyone curious could/would get passed it. But, it does remain the only workaround posted good, bad or ugly. I've half expected you to post something using p/invoke, or similar, since you're good at navigating the back doors into the API.

TonyT

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #35 on: March 13, 2009, 05:44:49 AM »
The workaround in this case, is simply to not to use a seperate
background thread.

I don't think it's a good idea to simply blow the user away
by switching to a newly opened document while they may
be in the middle of doing just about anything (like dragging
objects around, or perhaps have another dialog box open,
or what have you).

Do you?

I totally agree with you - anyone curious could/would get passed it. But, it does remain the only workaround posted good, bad or ugly. I've half expected you to post something using p/invoke, or similar, since you're good at navigating the back doors into the API.

MikeTuersley

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #36 on: March 13, 2009, 11:27:07 PM »
LOL Tony! I finally figured out where you are coming from - we are talking apples & oranges

Quote
I don't think it's a good idea to simply blow the user away by switching to a newly opened document while they may be in the middle of doing just about anything (like dragging objects around, or perhaps have another dialog box open, or what have you).

In this instance, I agree.

This is not what I was reading into Bobby's original post. Having some type of background threading is a necessity if you are dealing with backend data sources. I read into Bobby's post that he wanted a long process to run then open a file and use a thread so the user could cancel the operation - MY 'BAD' there because I read more into it. For example, the user selects a new file to open. I override the open and submit the associated xrecord data back to the ERP system then open the requested document. While this is happening, there is a form [as I suggested] displayed that is showing some type of progress indicator and a button to cancel the operation [in case it's running too long or whatever].

Bobby C. Jones

  • Swamp Rat
  • Posts: 516
  • Cry havoc and let loose the dogs of war.
Re: BackgroundWorker & ShowModalDialog
« Reply #37 on: March 16, 2009, 09:07:01 AM »
That's the end goal, to process a request that, when is firing on all cylinders, takes 3 - 5 seconds and then opens the drawing.  There are times, however, that it could take much longer, and I need to give the user feedback on progress as well as provide an option to cancel the request altogether.  I certainly have no desire to blow the user away, well, at least not most of them :-)

Quote
I don't think it's a good idea to simply blow the user away by switching to a newly opened document while they may be in the middle of doing just about anything (like dragging objects around, or perhaps have another dialog box open, or what have you).

In this instance, I agree.

This is not what I was reading into Bobby's original post. Having some type of background threading is a necessity if you are dealing with backend data sources. I read into Bobby's post that he wanted a long process to run then open a file and use a thread so the user could cancel the operation ...].
Bobby C. Jones

TonyT

  • Guest
Re: BackgroundWorker & ShowModalDialog
« Reply #38 on: March 20, 2009, 09:11:48 PM »
Showing a progress UI with the option to cancel doesn't require
a seperate thread, and usually doesn't use one unless you want
to get fancy with AVI animations like Windows file copy.

If the operation involves some kind of loop or the 'atomic' operation
exposes some kind of event that's fired routinely during the process,
then the UI can be updated from the loop or event handler.

That's quite commonly how it's done, because in the overhwelming
number of cases I've seen, progress UIs are blocking (e.g., the user
must either wait or cancel, but can't do anything else).

OTOH if this is more an 'adventure in programming' or threading for
threading's sake, then that's another matter, but the fact remains
the the problem is easily solvable without threading.


That's the end goal, to process a request that, when is firing on all cylinders, takes 3 - 5 seconds and then opens the drawing.  There are times, however, that it could take much longer, and I need to give the user feedback on progress as well as provide an option to cancel the request altogether.  I certainly have no desire to blow the user away, well, at least not most of them :-)

Quote
I don't think it's a good idea to simply blow the user away by switching to a newly opened document while they may be in the middle of doing just about anything (like dragging objects around, or perhaps have another dialog box open, or what have you).

In this instance, I agree.

This is not what I was reading into Bobby's original post. Having some type of background threading is a necessity if you are dealing with backend data sources. I read into Bobby's post that he wanted a long process to run then open a file and use a thread so the user could cancel the operation ...].
« Last Edit: March 20, 2009, 09:58:55 PM by TonyT »

Bobby C. Jones

  • Swamp Rat
  • Posts: 516
  • Cry havoc and let loose the dogs of war.
Re: BackgroundWorker & ShowModalDialog
« Reply #39 on: March 23, 2009, 08:39:13 AM »
Originally this was a single threaded operation that did block the UI while reporting progress.  However, I could not think of a way other than threading to allow canceling.  The operation sends a request to a URL, processes the response, and acts accordingly.  I want to allow the user the ability to cancel while waiting for the response.

This isn't a critical application and I am using it as an opportunity to learn something new.  And that I have; mostly that I don't know jack.

Showing a progress UI with the option to cancel doesn't require
a seperate thread, and usually doesn't use one unless you want
to get fancy with AVI animations like Windows file copy.

If the operation involves some kind of loop or the 'atomic' operation
exposes some kind of event that's fired routinely during the process,
then the UI can be updated from the loop or event handler.

That's quite commonly how it's done, because in the overhwelming
number of cases I've seen, progress UIs are blocking (e.g., the user
must either wait or cancel, but can't do anything else).

OTOH if this is more an 'adventure in programming' or threading for
threading's sake, then that's another matter, but the fact remains
the the problem is easily solvable without threading.


That's the end goal, to process a request that, when is firing on all cylinders, takes 3 - 5 seconds and then opens the drawing.  There are times, however, that it could take much longer, and I need to give the user feedback on progress as well as provide an option to cancel the request altogether.  I certainly have no desire to blow the user away, well, at least not most of them :-)

Quote
I don't think it's a good idea to simply blow the user away by switching to a newly opened document while they may be in the middle of doing just about anything (like dragging objects around, or perhaps have another dialog box open, or what have you).

In this instance, I agree.

This is not what I was reading into Bobby's original post. Having some type of background threading is a necessity if you are dealing with backend data sources. I read into Bobby's post that he wanted a long process to run then open a file and use a thread so the user could cancel the operation ...].
Bobby C. Jones