[Closed] Running a fn inside a Struct in another Thread?
Hi there everyone,
I’m having problems with dotNET and multi threading (BackgroundWorker) inside a Struct.
I’m trying to create a general purpose Struct with various methods etc… to use in my workflow. I started with a method I need now, that takes a current maxFile and packs it externally in WinRAR via the Process class. I wanted to make this operation run in another thread so that I can still use Max while the process is being executed (packing certain large files takes time), however, I bumped into a problem I don’t really know how to deal with.
Here’s a snippet of the struct:
struct duberOps
(
duberPath = @"C:\duber",
sysPath = dotNetClass "System.IO.Path",
process = dotNetClass "System.Diagnostics.Process",
startInfo = dotNetClass "System.Diagnostics.ProcessStartInfo",
MainThread = dotnetobject "CSharpUtilities.SynchronizingBackgroundWorker",
fn runWinRARInBG sender ev =
(
for i = 1 to 10 do print ( "iter: " + (i as string) + " it works!" )
return "SOMETHING"
),
fn compressCurrentSceneFile method:#rar =
(
-- the path to the rar.exe file
local archiverPath = this.sysPath.Combine this.duberPath @"WinRAR\4.01_x64\Rar.exe"
local process = dotNetObject this.process
local startInfo = dotNetObject this.startInfo
-- multithreading support
this.MainThread.WorkerSupportsCancellation = true
this.MainThread.WorkerReportsProgress = true
dotNet.addEventHandler this.MainThread "DoWork" this.runWinRARInBG
if this.MainThread.IsBusy do this.MainThread.CancelAsync()
-- check whether the current file is saved to disk
if maxFileName != "" or maxFilePath != "" do
(
local completeFileName = this.sysPath.Combine maxFilePath maxFileName
if not this.MainThread.IsBusy do this.MainThread.RunWorkerAsync()
)
)
)
duberOps = duberOps()
As you can see, I’m using a similar approach to Lonerobot’s multithreading example. But, when executing the duberOps.compressCurrentSceneFile() function that should trigger the runWinRARInBG() function in another thread via the dotnetobject “CSharpUtilities.SynchronizingBackgroundWorker” object, it only returns undefined. That’s it.
But when I add the dotNet eventHandler to a globally declared function outside that Struct, it runs it without problems.
Am I missing something here? Why isn’t the backgroundWorker triggering the function inside the same struct?
Thanks a lot for any tips in advance!
struct duberOps
(
MainThread = dotnetobject "CSharpUtilities.SynchronizingBackgroundWorker",
fn runWinRARInBG sender ev =
(
for i = 1 to 10 do print ( "iter: " + (i as string) + " it works!" )
return "SOMETHING"
),
fn compressCurrentSceneFile method:#rar =
(
MainThread.WorkerSupportsCancellation = true
MainThread.WorkerReportsProgress = true
dotNet.addEventHandler MainThread "DoWork" runWinRARInBG
if MainThread.IsBusy do MainThread.CancelAsync()
if not MainThread.IsBusy do MainThread.RunWorkerAsync()
)
)
duberOps = duberOps()
duberops.compresscurrentscenefile()
Do structs support .this property? Is this something new?
This code seems to work for me.
I only discovered it a few months ago but it seems to have been around since max 2010. The only mention of it in the reference as far as i know is the section about the on create and on clone events.
lo’s version (without the ‘this’) works for me too. I think ‘this’ is only necessary when you need to access a property or function defined after the calling function in the same struct. Also handy in the on clone event.
I dont know if I recall it correctly, but I think there was a problem with structs/functions and eventhandlers.
Oh man! I hope it’s not another bug. :banghead:
.this is nothing new. It’s a pointer referencing the actual object you’re calling it within. So, in a Scripted Controller .this will return the scripted controller itself. In a Struct, .this will return the struct object itself, without having to call it explicitly by name.
Still, it’s very, very far from .self in Python, for example.
By the way, even when not using .this, but calling the Struct by its name I get the same behavior.
Got it working!
I had to include the MainThread object inside the function itself! Then it works correctly.
Strange behavior.
Check this out:
http://forums.cgsociety.org/showthread.php?f=98&t=850340
And Light solution on the same thread: http://forums.cgsociety.org/showpost.php?p=6338136&postcount=14