2

I'm in a static class in a background thread , but i want to create a new GUI component, to do this i need the main thread of the application to executing the method.

How can I do this?

[note i dont think i can use InvokeRequired as its a static class not a gui]

David

OwenP
  • 24,950
  • 13
  • 65
  • 102
GreyCloud
  • 3,030
  • 5
  • 32
  • 47
  • Possible duplicate of [C# Multithreading -- Invoke without a Control](https://stackoverflow.com/questions/1739283/c-sharp-multithreading-invoke-without-a-control) – J... Aug 31 '18 at 17:09

3 Answers3

4

To clarify this issue, you have a Static class on a secondary thread that you would like to have your main thread spawn a UI element from this class.

In order to do this you will need to setup an event in your static class, and then have your UI listen for that event. Even if its static this can be wired up. In your event handle code you can have your main UI call invoke to actually spawn the UI element.

class Program
{
    static void Main(string[] args)
    {
        DoSomething.OnNeedsUI += new EventHandler<EventArgs>(DoSomething_OnNeedsUI);
        Thread t = new Thread(new ThreadStart(DoSomething.Work));
        t.Start();
    }

    private static void DoSomething_OnNeedsUI(object sender, EventArgs e)
    {
        Console.Write("Call Back Handled Here");
    }
}


public static class DoSomething
{
    public static void Work()
    {
        for (int i = 0; i < 10; i++)
        {

            Thread.Sleep(5000);
            // Raise your Event so the tUI can respond
            RaiseOnNeedsUI();
        }
    }

    //  Create a Customer Event that your UI will Register with
    public static event EventHandler<EventArgs> OnNeedsUI;
    private static void RaiseOnNeedsUI()
    {
        if (OnNeedsUI != null)
            OnNeedsUI(null, EventArgs.Empty);
    }
Salizar Marxx
  • 917
  • 6
  • 11
  • 1
    Just to clarify, this sample would still need to invoke in the event handler, correct? (as mentioned in the solution) Events by themselves don't cross threads, right? – Marcus10110 Sep 14 '14 at 17:46
  • 7
    This answer is wrong - `DoSomething_OnNeedsUI` will execute in the worker thread here, not the main thread. Events are just multicast delegates - they don't magically cross thread boundaries. – J... Aug 31 '18 at 17:08
2

Your static class needs a reference to some instance class that was created on the UI thread, preferably a control. Since you're creating a control, you probably have some form/window in mind for that control, so you'll need a reference anyway. You can use the form's Invoke() method to marshall a call that will create the control on the UI thread.

OwenP
  • 24,950
  • 13
  • 65
  • 102
  • the static class is creating a component via the activator and returning it so i dont have a reference to a gui component ... is the only option to refactor so that i do ? – GreyCloud Oct 13 '10 at 22:36
  • I can't think of a way to definitively get the UI thread other than enumerating all threads associated with a process and taking a wild guess. I had a look at the properties on the Application class and System.Threading.Thread, but nothing seemed to lead to an answer. – OwenP Oct 13 '10 at 22:42
  • +1 as I have refactored to use this as a solution [before Salizar answered]. – GreyCloud Oct 14 '10 at 08:15
1

You can either pass an instance of a UI control to the method (then fall Invoke on that), else wrap up what you want as a delegate; for example:

static void DoStuff(..., Action<string> updateMessage) {
    ...
    //loop
    updateMessage(currentState);
}

With:

DoStuff(..., msg => this.Invoke((MethodInvoker)delegate{
    this.Text = msg;
}));
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • I'm not entirely certain that's going to work; isn't the this reference inaccessible from a static class? I may just be missing some context. – OwenP Oct 13 '10 at 22:39
  • @OwenP - if you pass it into the method as a parameter, it is fully accessible... – Marc Gravell Oct 14 '10 at 07:05