views:

417

answers:

3

Hi there, I have a Timer that monitors certain conditions (like if a Process is running) and when those conditions are met I must create a hook (SetWinEventHook). The problem is that the hook must be created on the main thread, otherwise my callback doesn't return.

How to do that? I've tried everything, and the only way that this worked, was using a System.Windows.Forms.Timer, but I don't want the my monitoring timer running in the same thread as my application, so I want to use Timers.Timer or Threading.Timer.

Luiz Borges

PS: It is a GUI-less app (notify icon only).

+1  A: 

If you have a GUI-less application you should use a System.Threading.Timer

Comparing the Timer Classes in the .NET Framework Class Library

If you want the timer event to access a UI control then you need to marshall onto the UI thread using Invoke().

Mitch Wheat
I already studied this comparative, I based my tests on that.There is no UI control in my app, I just to execute a method on the main thread so that my Hook is created on it.Luiz Borges
A: 

When you app starts, create a static variable to store a reference to windows form object. If you actually start the thread from main you could also pass the forms object reference into the thread as a parameter.

EDIT: Actually you only need the static if you need the threads to access the object after its been created. Otherwise you should be able to pass the form reference as a parameter in almost all cases.

i.e

internal static System.Windows.Form mainForm;

public static void Main(string[] args)
{
    mainForm = new NotifyIconApplication();

    //start thread here.

    Application.Run(mainForm);
}

Your thread can now access the reference to your mainForm.

You could now call a method on that object, however you will need to invoke the method on the forms thread to perform it from here.

internal void MyMethod(object params)
{
    if(this.InvokeRequired)
    {
        //This causes your hook creation to run on the forms thread
        this.Invoke(DelegateToMyMethod, params); 
    } 
    else 
    {
        //Create hook.
    }
}
Spence
A: 

Hey Spence, I guess I wasn't so clear, I don't have a main-form. My app is controled just by a NotifyIcon and a form is never needed (or even created).

My code is somewhat link that:

public class Notify : ApplicationContext
{
// class definition ...

public Notify()
{
// create Timers.Timer here
}

public void MakeHook()
{
// create hook, this should be called on the main thread
}

public static void Main(string[] args)
{
Notify notify = new Notify();
Application.Run(notify);
}
}

I use an ApplicationContext, that seemed to be the most adequate solution to a form-less app.

Luiz Borges

PS: I wasn't login when I made the question, that why I'm a "diferent user" now...

Luiz Borges