PDA

View Full Version : [CLOSED] Allowed activities in task manager



cwolcott
Oct 22, 2013, 2:08 PM
What should not be done in ThreadPool.QueueUserWorkItem()?

I have several processes that perform multiple actions (Update primary table in database, send out an email, update secondary tables in database, refresh columns in a grid store and publish on the MessageBus to update other fields in detail panels.

My original design just showed a mask "Processing ..." and everything was fine. Then one day I noticed I was hanging for a while and eventually a message box was displayed alerting me that an email could not be sent out. So I decided to alter the design and add a task manager to handle the longaction and within the long action update a session variable to let the user know what step was being processed (Just like the example TaskManager -> Basic -> Poll Server) which you created because of this thread [CLOSED] DirectEvent Mask Message (http://forums.ext.net/showthread.php?22527-CLOSED-DirectEvent-Mask-Message&p=97929&viewfull=1#post97929) post #14.

An additonal thread about this was discussed in Oct 2011 - [CLOSED] ProgressBar Server Side Update (http://forums.ext.net/showthread.php?15959-CLOSED-ProgressBar-Server-Side-Update&p=67568&viewfull=1#post67568) with some good suggestions in post #9.

I did not try to implement Marcelo's suggestion yet about resetting the Session for the thread because I passed in all of the session variables that my process needed, but as noted in Post #15 (http://forums.ext.net/showthread.php?22527-CLOSED-DirectEvent-Mask-Message&p=97929&viewfull=1#post97929) my next issue was when trying to update grid store record elements and then commit the record.

After forgetting that I had posted about this last December I finally tracked it down to the ResourceManager.ScriptOrderNumber which uses HttpContext.Current which is null in the thread.

In my thread I performing the following:



...
// Grab the row that is being updated (Works just fine)
var requestSelected = RequestGridPanel.GetStore().GetById(requestId);

// ** Loop through the dictionary of updates (Problem when in a thread process)
foreach (var column in columnUpdates)
requestSelected.Set(column,Key, column.Value);

requestSelected.Commit();
...


By calling requestSelected.Set eventually the Ext.Net.BaseControl.AddScript(string script) method is called executing the following line:



this.ProxyScripts.Add(ResourceManager.ScriptOrderN umber, TokenUtils.ReplaceRawToken(TokenUtils.ParseTokens( script, this)));


The script parameter is "App.Requests_Store.getById(5233).set(\"ActUserNm\", \"BobSmith\");". It is failing with "An entry with the same key already exists." and the reason is ResourceManager.ScriptOrderNumber is always returning 0 when in the thread thus the second item in the foreach loop fails because the first item was already added.

Do you believe that Marcelo's suggestion is the best one?
Should certain actions never occur in a thread?

Any suggestions?

cwolcott
Oct 22, 2013, 5:13 PM
I implemented Marcelo's suggestion and the thread now has access to the HttpContext.Current and the segment of code below is execute in the store and added into the ProxyScripts. Eventually the thread is stopped and I believe that the modifications to the store never actually occur.

So should a thread not access UI components? If it is allowed how can i get the items in the proxyscript to execute before the thread stops.



...
// Grab the row that is being updated (Works just fine)
var requestSelected = RequestGridPanel.GetStore().GetById(requestId);

// ** Loop through the dictionary of updates (Problem when in a thread process)
foreach (var column in columnUpdates)
requestSelected.Set(column,Key, column.Value);

requestSelected.Commit();
...

Daniil
Oct 22, 2013, 5:45 PM
Hi Chris,

Such stuff is supposed to be used during DirectEvents and DirectMethods only.

Unfortunately, it is not going to work in an individual thread.

Well, theoretically it might be possible, but it is really a big deal and goes out from the toolkit context.

cwolcott
Oct 22, 2013, 5:53 PM
Darn, was hoping there would be an answer, but I understand. Time to move back to the previous commit and get rid of all that work.

Please close the thread.

cwolcott
Oct 23, 2013, 6:34 PM
Winner, Winner, Chicken Dinner!

Software development is so much fun because there are multiple ways to accomplish a design. I went home last night, had a great dinner with the kids and actually dreamed the solution. I then woke up at 4:30 am, drove to work and an hour later had everything working.

As you eluded to yesterday I should not be updating UI components from within the LongAction of the task. So what I did was add the dictionary holding the stores columns and new values (columnUpdates) to a Session variable "RqUpdates". Then I defined the Task OnStop handler to perform a couple of actions. One of which was to call a DirectMethod to process the columnUpdates from the session variable, if it existed.

Another potential issue were errors that might occur during the LongAction, like DB failures and SMTP failures. If they occurred I added another dictionary to a Session variable "RqAlert" containing the title and message. Within the DirectMethod if the "RqAlert" session variable existed I showed an X.Msg.Alert.

Thanks for reading through the massive amount of threads across all the forums and supporting your users. LIFE IS GOOD!!

Daniil
Oct 24, 2013, 5:04 AM
Excellent! Thank you for sharing that and for the kind words!