Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Handling Abort for Long running operations in MFC

Handling Abort for Long running operations in MFC

Scheduled Pinned Locked Moved C / C++ / MFC
c++mobilecomdesignalgorithms
7 Posts 3 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    MuraliKrishnaP
    wrote on last edited by
    #1

    I am trying to find an easier way to handle Abort mechanism for long running operations. I tried googling all CP articles but, still I can't find a better way to solve my problem. My application has huge code base. I have to carefully design the Abort functionality without making major changes to existing code. I want the future programmers to understand and debug the code easily. Adding more complexity, the application creates GUI / Glyphs on the fly. Here are some solutions I found on CP: 1. Using PeekMessage loop and PumpMessage during long running operations. - Not feasible for huge apps, not easy to debug. Abort will be on and off. 2. Using worker thread for long operations, main thread becomes free, post completion status to main thread after completing long operation. - Gives most responsive app but, needs redesign of total code, exception handling will be difficult. 3. Using worker thread for creating glyphs, performing long operations and all from one single Worker Proc. - Not at all recommended. Window handles cannot be easily used from other threads without using CWnd::FromHandle() or Attach() methods. If there are any SendMessage() calls, it will lead to lead locks. 4. Using UIThread. - Will show an awkward Abort dialog every time but, solves problem very simply without having to change major code. There are other problems, The UIThread Abort dialog shows as seperate task bar button. This can be made as part of main app by making it tool window or by creating hidden window as parent. But, as the main window is busy, showing UIThread dialog when main thread is busy is something I need to solve. I read one article: http://www.drdobbs.com/184416859[^] but can't understand the way to make it work. I request you people to take a look. In this, the author creates a new UIThread and the InitInstance waits until the long operation is done. I can't understand how this makes the main thread responsive. I tried it and it didn't work. As you can understand, I am seeing all combinations. The Dr Dobbs article showed hope initially but did not work for me. Please guide me with your experience. Thanks, Murali Krishna.

    A _ 2 Replies Last reply
    0
    • M MuraliKrishnaP

      I am trying to find an easier way to handle Abort mechanism for long running operations. I tried googling all CP articles but, still I can't find a better way to solve my problem. My application has huge code base. I have to carefully design the Abort functionality without making major changes to existing code. I want the future programmers to understand and debug the code easily. Adding more complexity, the application creates GUI / Glyphs on the fly. Here are some solutions I found on CP: 1. Using PeekMessage loop and PumpMessage during long running operations. - Not feasible for huge apps, not easy to debug. Abort will be on and off. 2. Using worker thread for long operations, main thread becomes free, post completion status to main thread after completing long operation. - Gives most responsive app but, needs redesign of total code, exception handling will be difficult. 3. Using worker thread for creating glyphs, performing long operations and all from one single Worker Proc. - Not at all recommended. Window handles cannot be easily used from other threads without using CWnd::FromHandle() or Attach() methods. If there are any SendMessage() calls, it will lead to lead locks. 4. Using UIThread. - Will show an awkward Abort dialog every time but, solves problem very simply without having to change major code. There are other problems, The UIThread Abort dialog shows as seperate task bar button. This can be made as part of main app by making it tool window or by creating hidden window as parent. But, as the main window is busy, showing UIThread dialog when main thread is busy is something I need to solve. I read one article: http://www.drdobbs.com/184416859[^] but can't understand the way to make it work. I request you people to take a look. In this, the author creates a new UIThread and the InitInstance waits until the long operation is done. I can't understand how this makes the main thread responsive. I tried it and it didn't work. As you can understand, I am seeing all combinations. The Dr Dobbs article showed hope initially but did not work for me. Please guide me with your experience. Thanks, Murali Krishna.

      A Offline
      A Offline
      Aescleal
      wrote on last edited by
      #2

      I'd go for using the active object pattern [1] - that gives you parallism without bending your current code to much. "Just" make the classes with the long execution time methods active. It's similar to using worker threads but the implementation of those worker threads are (mostly) hidden within the classes so they appear like normal objects. The bad news is that writing (or borrowing) the scaffolding to implement active objects can be a bit of a pain in the bum. However once you've done it it's fairly easy to make any class active by implementing a fairly thin proxy class to the app. Perhaps try it with a toy application and see if it's worth the pain? Cheers, Ash [1] In brief the idea of the active object pattern is that every object has it's own worker thread. When method calls are made on the object the calls get queued and run whenever the worker thread is next idle. Return values are dished back to the calling function as futures - which look like normal variables but block when read until their completing worker thread signals them. http://www.cs.wustl.edu/~schmidt/PDF/Act-Obj.pdf[^] describes the pattern but it may take several readings to avoid the "whoaaa, this is well over complicated!" feeling.

      M 1 Reply Last reply
      0
      • A Aescleal

        I'd go for using the active object pattern [1] - that gives you parallism without bending your current code to much. "Just" make the classes with the long execution time methods active. It's similar to using worker threads but the implementation of those worker threads are (mostly) hidden within the classes so they appear like normal objects. The bad news is that writing (or borrowing) the scaffolding to implement active objects can be a bit of a pain in the bum. However once you've done it it's fairly easy to make any class active by implementing a fairly thin proxy class to the app. Perhaps try it with a toy application and see if it's worth the pain? Cheers, Ash [1] In brief the idea of the active object pattern is that every object has it's own worker thread. When method calls are made on the object the calls get queued and run whenever the worker thread is next idle. Return values are dished back to the calling function as futures - which look like normal variables but block when read until their completing worker thread signals them. http://www.cs.wustl.edu/~schmidt/PDF/Act-Obj.pdf[^] describes the pattern but it may take several readings to avoid the "whoaaa, this is well over complicated!" feeling.

        M Offline
        M Offline
        MuraliKrishnaP
        wrote on last edited by
        #3

        Ash, Thanks for your quick reply. I am looking at the pdf and trying to understand. I think it will take a day or two. BTW, I forgot to mention. My application uses CORBA synchronous RMI calls. I took a quick look of the pdf and saw some know issues.. didn't read completly. Thanks, Murali Krishna

        M A 2 Replies Last reply
        0
        • M MuraliKrishnaP

          Ash, Thanks for your quick reply. I am looking at the pdf and trying to understand. I think it will take a day or two. BTW, I forgot to mention. My application uses CORBA synchronous RMI calls. I took a quick look of the pdf and saw some know issues.. didn't read completly. Thanks, Murali Krishna

          M Offline
          M Offline
          MuraliKrishnaP
          wrote on last edited by
          #4

          My bad, I misread it. it is known uses. (not issues) :)

          1 Reply Last reply
          0
          • M MuraliKrishnaP

            Ash, Thanks for your quick reply. I am looking at the pdf and trying to understand. I think it will take a day or two. BTW, I forgot to mention. My application uses CORBA synchronous RMI calls. I took a quick look of the pdf and saw some know issues.. didn't read completly. Thanks, Murali Krishna

            A Offline
            A Offline
            Aescleal
            wrote on last edited by
            #5

            If you're using CORBA then using the active object pattern shouldn't be too hard a concept to grasp. You can think of a CORBA object as an active object running in another process/on another machine. One option you might have might be to stick the long running stuff in their own processes and use CORBA, although you'll loose a bit (a lot?) of efficiency that way. It could save you the balls ache of implementing the active object pattern though and all the other problems you have with multiple threads although if you're using a lot of complex types in the interface marshalling might be hell. Cheers, Ash

            M 1 Reply Last reply
            0
            • M MuraliKrishnaP

              I am trying to find an easier way to handle Abort mechanism for long running operations. I tried googling all CP articles but, still I can't find a better way to solve my problem. My application has huge code base. I have to carefully design the Abort functionality without making major changes to existing code. I want the future programmers to understand and debug the code easily. Adding more complexity, the application creates GUI / Glyphs on the fly. Here are some solutions I found on CP: 1. Using PeekMessage loop and PumpMessage during long running operations. - Not feasible for huge apps, not easy to debug. Abort will be on and off. 2. Using worker thread for long operations, main thread becomes free, post completion status to main thread after completing long operation. - Gives most responsive app but, needs redesign of total code, exception handling will be difficult. 3. Using worker thread for creating glyphs, performing long operations and all from one single Worker Proc. - Not at all recommended. Window handles cannot be easily used from other threads without using CWnd::FromHandle() or Attach() methods. If there are any SendMessage() calls, it will lead to lead locks. 4. Using UIThread. - Will show an awkward Abort dialog every time but, solves problem very simply without having to change major code. There are other problems, The UIThread Abort dialog shows as seperate task bar button. This can be made as part of main app by making it tool window or by creating hidden window as parent. But, as the main window is busy, showing UIThread dialog when main thread is busy is something I need to solve. I read one article: http://www.drdobbs.com/184416859[^] but can't understand the way to make it work. I request you people to take a look. In this, the author creates a new UIThread and the InitInstance waits until the long operation is done. I can't understand how this makes the main thread responsive. I tried it and it didn't work. As you can understand, I am seeing all combinations. The Dr Dobbs article showed hope initially but did not work for me. Please guide me with your experience. Thanks, Murali Krishna.

              _ Offline
              _ Offline
              _Superman_
              wrote on last edited by
              #6

              Not sure if this will be of help to you, but if you're using SendMessage from one thread to another, you can use the ReplyMessage API to achieve concurrency.

              «_Superman_»
              I love work. It gives me something to do between weekends.

              Microsoft MVP (Visual C++)

              Polymorphism in C

              1 Reply Last reply
              0
              • A Aescleal

                If you're using CORBA then using the active object pattern shouldn't be too hard a concept to grasp. You can think of a CORBA object as an active object running in another process/on another machine. One option you might have might be to stick the long running stuff in their own processes and use CORBA, although you'll loose a bit (a lot?) of efficiency that way. It could save you the balls ache of implementing the active object pattern though and all the other problems you have with multiple threads although if you're using a lot of complex types in the interface marshalling might be hell. Cheers, Ash

                M Offline
                M Offline
                MuraliKrishnaP
                wrote on last edited by
                #7

                Hi Ash, I appreciate your interest in helping me. I am still finding a hard time to solve this. May be I am not smart enough to design this properly. I went through the pattern. Even with this active object, if I have to make synchronous calls, the client must be blocked till the message is received. Or may take time some where in client also. Consider this: (simplified for reading) When I start an operation, My application performs following.. 1. Connect to server (may take 2 secs) 2. Create a GUI for showing some data (milli secs) 2. Get data (RMI) (40 secs) 3. Update GUI (milli secs) 5. Based on the above data start creating next GUI. 6. Create next GUI. 6. Get modified data for second GUI. (RMI) (4 mins!) 7. Update second GUI Till now these are sequential in my application. User can always create n number of GUIs. Each GUI creation and updation may require n RMI calls and they are synchrounous. Meaning, each RMI call is blocked till it is received and the marshalling args are huge. I may also get MBs of data. Example: Consider following call stack. DataIDL::GetData() // Use proxy to get data. Blocked till the data is fetched. Glyph::GetData() // After glpyh creation GlyphsHandler::Execute() // Creates Glyph get data and Update Glyph Doc::Execute() // Execution start of all Glyphs Doc starts Execution. Glyphshandler creates glyphs, gets data and updates glyph. It goes on for all glyphs. Now as it all sequential, I cannot decouple each IDL call to threads as the next call depends upon previous call's data. Hope I am not taking too much of your time. Is it possible to asynchronously decouple the IDL getdata using active object so that the next call will have no effect? Many thanks for your advices till now. Murali Krishna

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups