Results 1 to 8 of 8

Thread: Add-in UI Responsiveness / Threads

  1. #1
    Member
    Join Date
    2010-06
    Location
    Brisbane, Australia
    Posts
    25
    Login to Give a bone
    0

    Default Add-in UI Responsiveness / Threads

    Hi all,

    Has anyone had any luck in making an add-in with a UI that remains responsive while getting Revit to do something heavy?

    I'm automating a few things that can keep Revit busy for a while and I'd like to provide a window displaying overall progress. As such, I'd really like this window to remain responsive while Revit is busy.

    I understand why this is difficult to do. I'm just wondering whether anyone has found a reasonable way around this. So far I've tried doing the heavy bits on a background thread (I know, I've read the warnings but had to try for myself). This proved unworkable so I tried running the (WPF based) UI on a new thread which works well outside of Revit, but has problems when hosted by Revit (I suspect this is related to the underlying interop).

    Anyone got any ideas? Is there some trick to getting a new UI thread working in Revit?

    I'm now considering taking the UI out of process, so when my command executes I'll kick off a new process to handle the UI. This solution is more complicated than I'd like but I can't see any reason for it to not work, and I can't think of anything simpler.

    Cheers.

  2. #2
    I could stop if I wanted to Danny Polkinhorn's Avatar
    Join Date
    2003-12
    Location
    San Francisco, CA
    Posts
    448
    Login to Give a bone
    0

    Default Re: Add-in UI Responsiveness / Threads

    This version of Find and Replace has some UI threads going, but they're not 100% reliable. I found that the actual processing was happening a little slower than what was being reported. It doesn't make any sense to me, but that's what I was seeing in a different application of the same principles. For example, when it was completed, I would report "405 items replaced" in a message box, but the original UI was showing that it was still processing and replacing "420 of 600". Something along those lines. I'll chalk it up to improper programming on my part and a lack of true multi-threading support in Revit.

    HTH,

  3. #3
    AUGI Addict
    Join Date
    2003-11
    Location
    New Zealand
    Posts
    1,116
    Login to Give a bone
    0

    Default Re: Add-in UI Responsiveness / Threads

    If you're using 2011 use the Idle event. There is a factory post in the SDK I think on threading issues. It can be done reliably but it's not straightforward, nothing to do with Revit as such.

    IMO using the Idle event will allow you to deal with 90% of projects that require an async component.

    Cheers,

    Guy

  4. #4
    Member
    Join Date
    2010-06
    Location
    Brisbane, Australia
    Posts
    25
    Login to Give a bone
    0

    Default Re: Add-in UI Responsiveness / Threads

    Quote Originally Posted by GuyR View Post
    If you're using 2011 use the Idle event. There is a factory post in the SDK I think on threading issues. It can be done reliably but it's not straightforward, nothing to do with Revit as such.

    IMO using the Idle event will allow you to deal with 90% of projects that require an async component.
    Thanks Guy. I agree the Idling event is very useful, but it doesn't help in this scenario. One thing I'm doing is calling Document.Export() and this can take quite a while to return (sometimes 30+ seconds), during which time the Idling event isn't raised.

    Can you elaborate on "It can be done reliably but it's not straightforward"? From what I'm seeing it seems to be related to the indirect mapping of OS threads to managed threads, and I can't see how it could ever be reliable.

    Some more detail:

    I had read a few blog posts on the threading issues with the Revit API and decided to try creating a secondary thread to handle the API calls, leaving the main thread for the UI. I found that some calls threw exceptions, and other calls just silently failed (i.e. Document.Export() returned false immediately without actually exporting anything).

    This is when I changed my approach to spawn a new thread for the UI and keep the initial thread for the API calls. When I do this, my UI is responsive initially but then becomes unresponsive when I call Document.Export().

    Cheers.

  5. #5
    AUGI Addict
    Join Date
    2003-11
    Location
    New Zealand
    Posts
    1,116
    Login to Give a bone
    0

    Default Re: Add-in UI Responsiveness / Threads

    Ah I see, well for an API call such as Export() Idle/threading isn't going to help you, you're one of the 10% cases When I talk about using threads successfully it's either to ensure the UI is responsive or interacting with customer code that can be threaded.

    You have to be careful using backgroundworker with .NET Revit object lifecycle issues. Is about as simple as I can explain it without posting a LOT of code.

    Here is the info from Arnost on Jeremy's blog: http://thebuildingcoder.typepad.com/...nd-idling.html

    Bottom line is everything needs to happen on the main Revit thread while a command is running. So exporting has to be synchronous. For exporting the only other option is firing off multiple instances of the model and exporting from each one, kinda like batch rendering. I'd only consider this though if exporting was taking hours or the user wanted to be able to keep working. Not straightforward to code though, however it has got much easier in 2011 with the Idle event as an asynchronous conduit. Plus only really good option if you're running quadcores and lots of RAM etc.

    In short no quick fix for this one I'm afraid.

    Cheers,

    Guy

  6. #6
    Active Member
    Join Date
    2005-09
    Posts
    69
    Login to Give a bone
    0

    Default Re: Add-in UI Responsiveness / Threads

    Our applications do some fairly heavy processing and I "played" around with this as well - having no experience with threading.
    I also ended up with the UI on the new thread, but I was having problems with using DoEvents to keep the UI responsive and ended up not using them, but making the Revit window the parent of my UI form seemed to help - unfortunately I didnt make a note of any references where that suggestion came from.
    The UI is responsive when running, but we dont call any single API method that takes a long time, like your Export call. When debugging I do occasionally get cross thread exceptions thrown, but so far no users have reported any such problems.

    Some code snippets
    Code:
                System.Diagnostics.Process currentProcess = System.Diagnostics.Process.GetCurrentProcess();
                System.IntPtr hWndRevit = currentProcess.MainWindowHandle;
                m_testForm = new ImportForm(hWndRevit, m_sImportName);
    
                Thread t = new Thread(new ThreadStart(new Shared.AppState(m_testForm).RunApp));
                t.SetApartmentState(ApartmentState.STA);
                t.IsBackground = false;
                t.Start();
    --------------------
    Code:
            private void ImportForm_Load(object sender, EventArgs e)
            {
                IntPtr hWndTest = Handle;
                if (m_hWndRevit != IntPtr.Zero && hWndTest != IntPtr.Zero)
                    SetParent(hWndTest, m_hWndRevit);
            }
    ----------------------
    Last edited by david.bartliff; 2010-08-17 at 09:11 AM.

  7. #7
    Member
    Join Date
    2010-06
    Location
    Brisbane, Australia
    Posts
    25
    Login to Give a bone
    0

    Default Re: Add-in UI Responsiveness / Threads

    Thanks David. I remember reading something about making the Revit window the parent on the building coder blog.

    I've implemented a solution where I start another process to display the UI and it communicates with a WCF service hosted in my Revit addin on a separate thread. This works well but it adds more complexity than I'd like for the functionality I'm trying to achieve.

    As soon as I can find some time I'll try running the window on another thread within the Revit process again, with the parent window set to Revit's main window. I'm not totally convinced it'll keep my windows responsive though and even if it seems to work in some initial testing I'm not sure whether I'd trust it to always work that way given what I've seen so far...

  8. #8
    Member
    Join Date
    2011-09
    Posts
    2
    Login to Give a bone
    0

    Question Re: Add-in UI Responsiveness / Threads

    Hi msiebert,

    Thanks for having such great discussion on this Revit API threading topic. I have the same aim as you as i would like to invoke a long run code (batch element creating including columns, walls, slabs, beams...) as a add-in and on the same time keep my progress bar (new windows form)responsive.

    First, i sent my long run method(contains few for loops) to background thread, then i update the progress after each of the element has been created. In this case, my progress bar is in a main thread. Everything works fine until i came across with few problems and errors like below. i thinks this related to the misuse of threading in my program.


    Please let me know if you have any idea making a good threadsafe UI control while the Revit method still can be invoked correctly.

    Thanks.

Similar Threads

  1. 2012: New Threads
    By nealehiggs in forum ACA General
    Replies: 1
    Last Post: 2012-10-23, 02:37 PM
  2. Am I the only one? No Threads
    By Rocket in forum Revit MEP - General
    Replies: 6
    Last Post: 2011-01-11, 08:46 PM
  3. Cut threads
    By vladdavostock in forum AutoCAD 3D (2007 and above)
    Replies: 5
    Last Post: 2010-10-14, 01:08 PM
  4. threads
    By ebmanne in forum Inventor - General
    Replies: 18
    Last Post: 2008-08-08, 02:18 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •