How do you run a variable number of concurrent parametrizable infinite loop type of threads in C#?

随声附和 提交于 2021-02-11 14:23:00

问题


I am creating my first multithreading C#/.NET based app that will run on a Azure Service Fabric cluster. As the title says, I wish to run a variable number of concurrent parametrizable infinite-loop type of threads, that will utilize the RunAsync method.

Each child thread looks something like this:

        public async Task childThreadCall(...argument list...)
        {
            while (true)
            {
                try
                {
                    //long running code
                    //do something useful here
                    //sleep for an independently parameterizable period, then wake up and repeat
                }
                catch (Exception e)
                {
                    //Exception Handling
                }
            }
        }

There are a variable number of such child threads that are called in the RunAsync method. I want to do something like this:

        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            try
            {
                for (int i = 0; i < input.length; i++)
                {
                    ThreadStart ts[i] = new ThreadStart(childThreadCall(...argument list...));
                    Thread tc[i] = new Thread(ts);
                    tc[i].Start();
                }
            }
            catch (Exception e)
            {
                //Exception Handling
            }
        }

So basically each of the child threads run independently from the others, and keep doing so forever. Is it possible to do such a thing? Could someone point me in the right direction? Are there any pitfalls to be aware of?


回答1:


The RunAsync method is called upon start of the service. So yes it can be used to do what you want. I suggest using Tasks, as they play nicely with the cancelation token. Here is a rough draft:

protected override async Task RunAsync(CancellationToken cancellationToken)
{
    var tasks = new List<Task>();
    try
    {
        for (int i = 0; i < input.length; i++)
        {
            tasks.Add(MyTask(cancellationToken, i);
        }
        
        await Task.WhenAll(tasks);
    }
    catch (Exception e)
    {
        //Exception Handling
    }
}

public async Task MyTask(CancellationToken cancellationToken, int a)
{
    while (true)
    {
        cancellationToken.ThrowIfCancellationRequested();

        try
        {
            //long running code, if possible check for cancellation using the token
            //do something useful here
            await SomeUseFullTask(cancellationToken);
            
            //sleep for an independently parameterizable period, then wake up and repeat
            await Task.Delay(TimeSpan.FromHours(1), cancellationToken);
        }
        catch (Exception e)
        {
            //Exception Handling
        }
    }
}

Regarding pitfalls, there is a nice list of things to think of in general when using Tasks.

Do mind that Tasks are best suited for I/O bound work. If you can post what exactly is done in the long running process please do, then I can maybe improve the answer to best suit your use case.

One important thing it to respect the cancellation token passed to the RunAsync method as it indicates the service is about to stop. It gives you the opportunity to gracefully stop your work. From the docs:

Make sure cancellationToken passed to RunAsync(CancellationToken) is honored and once it has been signaled, RunAsync(CancellationToken) exits gracefully as soon as possible. Please note that if RunAsync(CancellationToken) has finished its intended work, it does not need to wait for cancellationToken to be signaled and can return gracefully.

As you can see in my code I pass the CancellationToken to child methods so they can react on a possible cancellation. In your case there will be a cancellation because of the endless loop.



来源:https://stackoverflow.com/questions/65139824/how-do-you-run-a-variable-number-of-concurrent-parametrizable-infinite-loop-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!