0

To understand my problem more precisely I would like to use a WPF application with two buttons as an example.

public RelayCommand Button1Command { get; private set; }
public RelayCommand Button2Command { get; private set; }

In my ctor:

Button1Command = new RelayCommand(Button1Method);
Button2Command = new RelayCommand(Button2Method);

public void Button1Method(object sender)
{
    //Should do some stuff but e.g. in ThreadId 2
    
}

public void Button2Method(object sender)
{
    //Should do some stuff but if Button1 was executed in ThreadId 2
    //this button Action should also be done in ThreadId 2
}

The following example:

User clicks on Button1 => Button1Method is started on a new thread with ID 2.

User clicks on Button2 => Button2Method is started at the earliest when Button1Method is finished but also on the same thread in which Button1Method was executed.

And the whole also in the other direction.

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
gacaba3982
  • 25
  • 4
  • are you trying to limit the number of running threads? – A Farmanbar Nov 19 '21 at 02:12
  • No I want to access external lib which works only if same Thread access it. All accesses from other threads will be rejected – gacaba3982 Nov 19 '21 at 02:16
  • So essentially you want a dedicated thread that will remain alive for the whole lifetime of the process, with the sole purpose of executing either the `Button1Method` or the `Button2Method`, whenever the relevant buttons are clicked, correct? – Theodor Zoulias Nov 19 '21 at 02:17
  • Yes, you can put it that way. – gacaba3982 Nov 19 '21 at 02:20
  • 1
    Related: [Run work on specific thread](https://stackoverflow.com/questions/30719366/run-work-on-specific-thread). Check the `SingleThreadTaskScheduler` class. It is probably sufficient for what you want to do. – Theodor Zoulias Nov 19 '21 at 02:25

1 Answers1

-1

The way I would do this, is by having a worker thread to which you can add Tasks to complete sequentially. You can press the buttons in any order, but it will always wait for the previous one task to complete first before continuing work.

public class MyClass
{
    private Queue<Func<Task>> _tasks;
    private Thread _workerThread;
    private bool _running;

    // Constructor   
    public MyClass()
    {
        // Initialize Variables
        _tasks = new Queue<Func<Task>>();
        _workerThread = new Thread(DoWork);

        // Start the thread.
        _workerThread.Start();
    }

    // Deconstructor
    ~MyClass() => _running = false;

    // Worker thread Function
    private void DoWork(object obj)
    {
        _running = true;

        while (_running)
        {
            if (_tasks.Count() > 0)
            {
                var task = _tasks.Dequeue();
                var taskResult = task.Invoke();
                taskResult.Wait();
            }
        }
    }

    // Your buttons
    public void ButtonAPressed() => _tasks.Enqueue(ActionA);
    public void ButtonBPressed() => _tasks.Enqueue(ActionB);

    // Tasks that you need to queue up
    private async Task ActionA() { /* Do Work */ }
    private async Task ActionB() { /* Do Work */ }
}
CorrieJanse
  • 2,374
  • 1
  • 6
  • 23