a_hamm99
a_hamm99

Reputation: 191

TaskScheduler with async sequential Tasks C#

I am executing some .py scripts async. One Script takes about 30 seconds to be executed. It could happen that two or even more Scripts are being selected in a timespan of two or three seconds. The Goal is to have a Scheduler which collects all the tasks and executes them one after the other. A FIFO functionality should be included. I 've tried the following Code just to try the functionality of the queuedTaskScheduler, but even that doesn't work.

QueuedTaskScheduler queueScheduler;
private TaskScheduler ts_priority1;
int pos = 0;
        public Form1()
    {
        InitializeComponent();
        queueScheduler = new QueuedTaskScheduler(targetScheduler: TaskScheduler.Default, maxConcurrencyLevel: 1);
        ts_priority1 = queueScheduler.ActivateNewQueue(1);
    }
        private void button3_Click(object sender, EventArgs e)
    {
        QueueValue(pos, ts_priority1);
        pos++;
    }

    private void button4_Click(object sender, EventArgs e)
    {
        changeString(pos);
        pos++;
    }
    private void changeString (int position)
    {
        var bea = "This is Thread " + position + " starting";
        MethodInvoker Labelupdate = delegate
        {
            label2.Text = bea;
        };
        Invoke(Labelupdate);

        Thread.Sleep(3000);
        bea = "Thread " + position + " is ending";

        MethodInvoker Labelupdate1 = delegate
        {
            label2.Text = bea;
        };
        Invoke(Labelupdate1);
        Thread.Sleep(1000);
    }
    private void updateLabel (string Lab)
    {
        MethodInvoker Labelupdate = delegate
        {
            label2.Text = Lab;
        };
        Invoke(Labelupdate);
    }
    private Task QueueTask(Func<Task> f, TaskScheduler ts)
    {
        return Task.Factory.StartNew(f, CancellationToken.None, TaskCreationOptions.HideScheduler | TaskCreationOptions.DenyChildAttach, ts);
    }

    private Task QueueValue(int position, TaskScheduler ts)
    {
        return QueueTask(async () =>
        {
            label2.Text = "This is Thread " + position + " starting";
            Thread.Sleep(3000);
            label2.Text = "Thread " + position + " is ending";
            Thread.Sleep(1000);
        }, ts);
    }

Upvotes: 2

Views: 1091

Answers (1)

a_hamm99
a_hamm99

Reputation: 191

I solved it. There is only need of a Semaphore. It is the same way as in this Thread Here is the Code:

private static SemaphoreSlim semaphore = new SemaphoreSlim(1);
 private Task QueueValue(int position, TaskScheduler ts)
    {
        return QueueTask(async () =>
        {
            await semaphore.WaitAsync();
            try
            {
                var at = "This is Thread " + position + " starting";
                updateLabel(at);
                await Task.Delay(3000);
                at = "Thread " + position + " is ending";
                updateLabel(at);
                await Task.Delay(1000);
            }
            finally
            {

                semaphore.Release();
            }

        }, ts);
    }

Many thanks!

Upvotes: 2

Related Questions