如何在C#中运行可变数量的并发参数化无限循环类型的线程? [英] How do you run a variable number of concurrent parametrizable infinite loop type of threads in C#?

查看:51
本文介绍了如何在C#中运行可变数量的并发参数化无限循环类型的线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建我的第一个基于C#/.NET的多线程应用程序,该应用程序将在Azure Service Fabric群集上运行.如标题所示,我希望运行可变数量的并发参数化无限循环类型的线程,这些线程将利用RunAsync方法.

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
                }
            }
        }

在RunAsync方法中调用了许多这样的子线程.我想做这样的事情:

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?

推荐答案

服务启动时将调用 RunAsync 方法.所以是的,它可以用来做你想做的事.我建议使用Tasks,因为它们可以很好地与取消标记一起使用.这是草稿:

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.

请记住,任务最适合I/O绑定的工作.如果您可以发布长期运行过程中到底要完成的操作,那么我可以改善答案,使其最适合您的用例.

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.

重要的一点是要尊重传递给RunAsync方法的取消令牌,因为它表明服务即将停止.它使您有机会优雅地停止工作.来自文档:

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:

确保传递给RunAsync(CancellationToken)的canceleToken受到尊重,并发出信号后,RunAsync(CancellationToken)会尽快退出.请注意,如果RunAsync(CancellationToken)已经完成其预期的工作,则无需等待cancelToken发出信号并可以正常返回.

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.

正如您在我的代码中看到的那样,我将 CancellationToken 传递给子方法,以便它们可以对可能的取消做出反应.在您的情况下,由于循环不断,将被取消.

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.

这篇关于如何在C#中运行可变数量的并发参数化无限循环类型的线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆