Notifications
Clear all

[Closed] Using .NET BackgroundWorker with MAXscript

when you try to apply a MeshSmooth modifier from another thread it’s very unsafe. and i want to repeat – you just apply the modifier, but not force to do calculation in another thread.

it would be much faster to disable refmessages (?maybe?), apply new instance of MeshSmooth to every object, collapse (if you need), enable messaging, and update the scene…

if you want to compete try to beat this code with your BackgroundWorker approach:

(
	delete objects

	bb = for k=1 to 1000 collect (box())

	gc()

	t0 = timestamp()
	h0 = heapfree

	disablerefmsgs()

	for b in bb do applymodifier b (MeshSmooth())

	enablerefmsgs()
	completeredraw()

	format "time:% heap:%\n" (timestamp() - t0) (h0 - heapfree)
)

Easy man. I used meshsmooth just as a test example.
I understand that it is useless scenario.
I’m going to return to this experiment a week lately.
And thanks for disablerefmsgs() reference, it seems to be useful feature.

1 Reply
(@denist)
Joined: 10 months ago

Posts: 0

… as a wrong example. try to show a good one

I am surprised by your perseverance. You show me a weak code (perhaps realizing that this is so), but you suggest that I try it nonetheless.
What’s the point?

post something that really works and we will discuss it.

This example shows posibility of modifing objects within BackgroundWorker without crashing the whole package. None more and none less.
It does nothing useful, ok. Nobody claims the opposite.
And at this stage its just an experiment.

it does NOT modify objects in another then main thread! there is nothing close to multi-threading in your example

I haven’t been on this forum for years, so I was overjoyed to see you still crushing it with style Denis.

so just to weigh in on this, as soon as you try to interface with anything on the UI thread, it completely negates any benefits of using the background worker. For pure mathematical calculations maybe, but the overall performance benefits are not really worth it IMHO. And yes, like Denis, I’ve also tried this and I’ve yet to find a scenario where it was desirable.

Hey guys, is there any way to pause main thread and wait for background workers to .reportProgress?

Right now to achieve this I create modal dialog and programmatically close it when all background workers are done. But I’m sure there could be more elegant solution.

rollout roll1 “”
(
)

fn testFn pArr =
(
cThread = pArr.argument.value[2]
t = 0
for i = 1 to 100000 do t += 1
threadArray[cThread].reportProgress 100 cThread
)

fn UpdateThread val =
(
busyArr[val.userstate] = false
if busyArr.isEmpty do destroyDialog roll1
format “Thread % finished busyArr:%\n” val.userstate busyArr
)

threadArray = #()
threadsCount = 12
cobj = undefined

busyArr = #{1…threadsCount}

for i=1 to threadsCount do
(
dotCobj = dotNetMXSValue #(cObj,i)
threadArray[i] = dotnetobject “CSharpUtilities.SynchronizingBackgroundWorker”
threadArray[i].workerReportsProgress = true
dotNet.addEventHandler threadArray[i] “DoWork” testFn
dotNet.addEventHandler threadArray[i] “ProgressChanged” UpdateThread
threadArray[i].RunWorkerAsync dotCobj
)
createDialog roll1 modal:true pos:[-200,0]
Format “Finished !!!”

Page 2 / 2