views:

94

answers:

3

Hi,

QUESTION: In .NET 3.5 WinForms apps, how do I access/call methods in UI thread from a separate thread, without passing a delegate?

EXAMPLE: Say I have some code I want to run both (a) manually when the user clicks a button, and (b) periodically called by a process which is running in a separate non-mainUI thread but without passing a delegate. [Simplistically I'm thinking that the class that has this method is already been constructed, and the main UI thread has a handle to it, therefore if the process running in the separate thread could just get a handle to it from the main-UI thread it could call it. Hopefully this is not a flawed concept]

BACKGROUND: I'm actually after a way to do the above for the case where my separate process thread is actually a job I schedule using quartz.net. The way the scheduler works I can't seem to actually pass in a delegate. There is a way to pass JobDetails, however it only seems to caters for things like string, int, etc. Hence what I'm after is a way to access the MainForm class for example, to call a method on it, from within the quartz.net job which runs in a separate thread.

Thanks

+1  A: 

.Net doesn't allow fiddling with the UI from a non-UI thread; There are ways around it such as Invoke, but this is the only way to (safely) do it without resorting to polling a shared object.

Rowland Shaw
Is there a way to get a handle to call Invoke without to pass the separate thread a delegate Rowland?
Greg
@Greg What code have you got at the moment for launching the threads?
Rowland Shaw
I'm using quartz.net...see the section Background in my post.
Greg
@Greg I'm not familiar with Quartz.Net - I'm assuming it would allow you to pass a reference to the UI control/form you want to update though (after all, how else would it know what work to do)?
Rowland Shaw
+1  A: 

You could try the BackgroundWorker control in the toolbox, this works for simple things.

eschneider
the only thing is that I'm jusing Quartz.net for scheduling - so it from within the scheduled quartz job (that implements IJob) that I want to be able to do it :(
Greg
+1  A: 

Assuming you have access to the MainForm, you can simply call any of it's methods, but those methods will then bear the burden of checking if they need to be marshalled to the UI thread and handle the delegate passing there.

So on your main form you could have a method:

public void UpdateProgress()
{
    if( this.InvokeRequired )
    {
        this.Invoke(UpdateProgress);
        return;
    }

    // do actual update of progress here
}
Patrick Steele
Hopefully not a dumb question, but I'm not sure how to get access to Mainform from within an Ijob quartz.net class, as you can not pass parameters to it. What if I make a static variable and method in MainForm, then get it via MainForm.getInstance()?
Greg
Yup, if you can't pass parameters, you could expose the main form via a static variable.
Patrick Steele
ok thanks - this sounds like the way to go then - hopefully this isn't break some sort of best practice for .NET winforms development
Greg