How can I queue up a function called by MainThread in C #?

I found many resources for calling a function on the UI thread, but I have some logic that is only allowed to run from the main thread. Is there a way to grab the dispatcher on the main thread and call it?

+3


source to share


3 answers


"Dispatcher" is a concept specific to a particular UI framework (here: WPF). There is no dispatcher that can be used to target any stream. Imagine the following flow:

while (true) Console.WriteLine("x");

      



How are you going to call something on this thread? This cannot be done because this thread is forever busy with something else. He doesn't cooperate.

I doubt you need to call something in the "main thread". But I'll answer the question literally. You need the main thread to communicate with and accept work from other threads. Maybe a queue Action

or a boolean flag that tells this thread something specific.

+6


source


You can use a combination of signal + data structures. Define a variable to hold the details of the required function call (perhaps a structure with parameters), and your main thread will periodically check if the call is required. Make sure to lock the required objects using multithreaded hooks. You can also have a signal object and have an initiator Monitor.Wait

on it and the main thread will signal when the function is done.



+1


source


Edit: The program the OP was asking about did indeed have a separate UI and main threads ...

You can create new threads / tasks at any time using

        tokenSource = new CancellationTokenSource();
        token = tokenSource.Token;

        Task.Factory.StartNew(() =>
        {
            doSomeWork();
        }, token);

      

A token is being used, so you can cancel the task. If something goes wrong or the task hangs, you can cancel it. You may have already read about TPL libraries, but if not, do it and see if it works for what you want to do.

To make my answer a little more complete, I wanted to add this ... I'm not sure if this may or may not work in your case, but in normal cases you would do something like this to update or work with objects on the main thread from the workflow.

    private void doSomeWork()
    {
        // do work here -->

        if (someObject.InvokeRequired)
        {
            someObject.BeginInvoke((Action)delegate() { someObject.Property = someValue; });
        }
        else
        {
            someObject.Property = someValue;
        }
    }

      

0


source







All Articles