0

I'd like some ideas of how I can make a thread in C# to work as kind of an entity, where it stays "waiting" for me to call some method, and then that method will be executed inside that thread, and not on the thread that called the method.

Let me give an example:

    public class ThreadClass
    {
        public void method1() { do something...}
        public void method2() { do something...}
        public void method3() { do something...}
    } //my class with methods I want to run in another thread than UI, no order specific, when I need it...

    public partial class Form1 : Form
    {
        private void button1_Click(object sender, EventArgs e)
        {
            //call method1, but it CANNOT RUN IN UI THREAD
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //call method2, but it CANNOT RUN IN UI THREAD
        }
    } //main thread and class

To sum up: My thread has to live "forever", doing nothing, and when I click some button etc, some method will run inside it.

I've tried to use while loop, but I don't know how to call different methods in random moments.

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
rkdobh
  • 1
  • 1
  • That's kind of what async/Task does ... https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/ – Fildor Mar 29 '22 at 14:57
  • https://stackoverflow.com/a/21684059/17034 – Hans Passant Mar 29 '22 at 15:06
  • Read up on the _Thread pool_. It's (very roughly) a pool of threads waiting to do work for you. You can dispatch work to the thread pool and it will do the work asynchronously (relative to the thread from which the work was dispatched). For example, you can call `Task.Run(method1);` to invoke `method1` asynchronously. You can also impose ordering on your asynchronicity by using the `async` and `await` keywords – Flydog57 Mar 29 '22 at 15:15
  • 1
    @Fildor thanks! It's the first time I'm seeing a microsoft guide that is actually easy to understand. – rkdobh Mar 29 '22 at 16:27
  • What would you like to happen if you click the `button1` and then click quickly the `button2`, before the execution of the `method1` has completed? Would you like to execute the `method2` concurrently with the `method1`, or instead wait until the `method1` completes and then start the `method2`? – Theodor Zoulias Mar 29 '22 at 18:01
  • Microsoft's Reactive Framework has an `EventLoopScheduler` class that does exactly what you want. – Enigmativity Mar 29 '22 at 22:50

1 Answers1

1

Microsoft's Reactive Framework has an EventLoopScheduler class that does exactly what you want. NuGet System.Reactive.

Try this:

void Main()
{
    EventLoopScheduler els = new EventLoopScheduler(); //IDisposable
    //starts a new thread and holds it until the instance is disposed.
    
    IDisposable scheduled1 = els.Schedule(() => Method1());
    IDisposable scheduled2 = els.Schedule(() => Method2());
    IDisposable scheduled3 = els.Schedule(() => Method3());

    //Once `Method1` completes `Method2` begins
    //Once `Method2` completes `Method3` begins

    IDisposable scheduled4 = els.ScheduleAsync((s, ct) => Method4Async(ct));

    scheduled1.Dispose(); //Doesn't cancel if started, but unschedules
    scheduled2.Dispose(); //Doesn't cancel if started, but unschedules
    scheduled3.Dispose(); //Doesn't cancel if started, but unschedules

    scheduled4.Dispose(); //Does cancel if started, if not unschedules

    els.Dispose(); //Allows thread to end
}

public void Method1() { /* do something... */ }
public void Method2() { /* do something... */ }
public void Method3() { /* do something... */ }

public async Task Method4Async(CancellationToken ct) { /* do something... */ }
Enigmativity
  • 113,464
  • 11
  • 89
  • 172