[Closed] Interface updates while busy
It would be helpful if someone posted a bare bones repro of their script and how they trigger it. Are you triggering the long calculation from a (modal) dialog, the utility panel, in a timer event…
I have found the usual solution is to do my heavy lifting on a background worker thread. There are lots of different ways to set this up, that’s why I’m interested in how what the problem script looks like now.
For the ‘why it works this way’ you might want to check out:
Preventing Hangs in Windows Applications
As a last resort you can probably call DisableProcessWindowsGhosting but your users will curse you …and your peers will know you cheated
This a user32 library call so you will have to expose it with a little bit of C#. DenisT has tons of examples of how to do this on the fly:
http://forums.cgsociety.org/showthread.php?f=98&t=850382&highlight=user32
.biddle
For me it is not always the heavy calculations that stall 3ds Max. Even adding modifiers on a bunch of objects can cause it. Well, some modifiers itself cause this issue, like the ProOptimizer and things like that that require a little bit of time.
I don’t see any benefits of doing these common things with a background worker although I need to take a closer look to be sure.
Davy
How about this one (in maxscript):
windows.processPostedMessages()
I gave it an occational call within my loop, seemed to work wonders for me…
btw, I didn’t find this in maxscript help, but if you type windows.giveMeAClue into the listener, you will get some
Also, I ran this by doing timestamps every iteration and then windows.processPostedMessages() every 3 seconds. The overhead for a 64 second process was about 1 second.
Great find.
I looked it up in the SDK –it’s in the mxsagni\windows.cpp sample code.
It’s in the 2011 SDK, but not in the 2009 SDK (I don’t have 2010 installed)
I guess I don’t feel too bad about not noticing it earlier
In 2011 you get:
windows.foo()
– Unknown property: “foo” in #Struct:windows(
getChildrenHWND:<fn>; Public,
getDesktopHWND:<fn>; Public,
getChildHWND:<fn>; Public,
postMessage:<fn>; Public,
getHWNDData:<fn>; Public,
sendMessage:<fn>; Public,
getMAXHWND:<fn>; Public,
addChild:<fn>; Public,
processPostedMessages:<fn>; Public)
but all 2009 has is:
windows.foo()
– Unknown property: “foo” in #Struct:windows(
getDesktopHWND:<fn>,
addChild:<fn>,
getChildrenHWND:<fn>,
getChildHWND:<fn>,
sendMessage:<fn>,
getMAXHWND:<fn>)
I can’t post the actual source, but all processPostedMessages does is
MSG msg;
while (PeekMessage(&msg, NULL, 0 , 0, PM_REMOVE)) then
(
MAXScript_interface->TranslateAndDispatchMAXMessage(msg);
)
max 2010 doesn’t have processPostedMessages… I don’t know how can it help. Probably I can call something to show the system that the max is busy. But it’s slow down my calculations. Any window messages slow down everything dramatically.
The hanging issue is all about Window Ghosting feature which was supported by MAX since version 2010. It causes problems. Not just hanging on long calculations. I have problems with some WPF controls (resizing), .NET transparent controls… So maybe it’s a cheating but I put DisableProcessWindowsGhosting() on startup and don’t see any problems anymore.
fn DisableProcessWindowsGhosting =
(
if classof (dotnet.GetType "DisableWindowsGhosting")!=dotNetObject do
(
local source = StringStream ("
using System.Runtime.InteropServices;
public class DisableWindowsGhosting
{
[DllImport(\"user32.dll\")]
public static extern bool DisableProcessWindowsGhosting();
}")
compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
compilerParams.ReferencedAssemblies.Add("System.dll");
compilerParams.GenerateInMemory = on
csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source as String)
flush source
close source
if (compilerResults.Errors.Count > 0 ) then
(
local errs = stringstream ""
for i = 0 to (compilerResults.Errors.Count-1) do
(
local err = compilerResults.Errors.Item[i]
format "Error:% Line:% Column:% %
" err.ErrorNumber err.Line err.Column err.ErrorText to:errs
)
format "%
" errs
undefined
)
else
(
compilerResults.CompiledAssembly.CreateInstance "DisableWindowsGhosting"
)
)
)
DisableWindowsGhosting = DisableProcessWindowsGhosting()
DisableWindowsGhosting.DisableProcessWindowsGhosting()
in 3ds max below 2011 version you can use (dotnetClass “Application”). doEvents ()
instead windows.processPostedMessages ()
That’s very cool, it fixes hanging windows and status bar.
windows.processPostedMessages() does nothing for me, my dialog still freezes with heavy calculations.
Is there a drawback when using this code below? I wonder why it isn’t the default behavior in max.
Thank you Track!
in 3ds max below 2011 version you can use (dotnetClass “Application”). doEvents () instead windows.processPostedMessages ()
What advantages of use (dotnetClass “Application”).doEvents () instead windows.processPostedMessages()?
(dotnetClass “Application”).doEvents() supported from max 9.
windows.processPostedMessages() supported from max 2011.