How To Use PXLongoperation
Today I want to write a few words on usage of PXLongOperation.
Compare two following scenarios:
Base.Save.Press(); try { PXLongOperation.StartOperation(Base, ()=> { //Some other code
Base.Save.Press();
with this:
Base.Save.Press(); var doc = Base.Document.Current; var orderType = doc.OrderType; var orderNbr = doc.OrderNbr; try { PXLongOperation.StartOperation(Base, ()=> { var grp = PXGraph.CreateInstance<SOOrderEntry>(); grp.Document.Current = grp.Document.Search<SOOrder.orderNbr>(orderNbr, orderType); grp.Save.Press(); });
and tell me what will be the difference in execution of those two types of code?
I spent pretty big amount of time wondering why in Acumatica source code I often seen scenario #2. Reason why I was puzzled is that I don't like to create instance of something, if I can use some variable that exists already.
And finally I've discovered reason on why scenario #2 is preferable. After our team spent some time on digging on the following use case scenario. We've used scenario #1 and QA gave us very interesting bug: some buttons on UI level got disabled after execution of #1 scenario. The only way to enable them in scenario #1 was just to call refresh of the page:
throw new PXRedirectRequiredException(Base, false, "Sales Orders");
which is not the worst in life of end user, but definetly not the most convenient. How to avoid total refresh of the screen? Use scenario #2.
Another important aspec of scenario #2 is usage of variables. Take note, that inside of PXLongOperation I don't use Base.Document.Current.OrderType. Instead I use local variables doc, orderType and orderNbr which is then used at async thread.
Summary
Starting from today I plan to use #2 whenever I will deal with multithreading scenarions. Otherwise some UI problems will become some kind of guarantee.