簡體   English   中英

如何在 C# 中運行可變數量的並發參數化無限循環類型的線程?

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

我正在創建我的第一個基於多線程 C#/.NET 的應用程序,它將在 Azure Service Fabric 集群上運行。 正如標題所說,我希望運行可變數量的並發參數化無限循環類型的線程,這將利用 RunAsync 方法。

每個子線程看起來像這樣:

        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 方法中調用的此類子線程數量不定。 我想做這樣的事情:

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

所以基本上每個子線程都獨立於其他線程運行,並且永遠這樣做。 有可能做這樣的事情嗎? 有人能指出我正確的方向嗎? 有什么陷阱需要注意嗎?

RunAsync方法在服務啟動時被調用。 所以是的,它可以用來做你想做的事。 我建議使用任務,因為它們可以很好地與取消令牌配合使用。 這是一個粗略的草稿:

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

關於陷阱,有一個很好的列表,列出了在使用任務時一般要考慮的事情。

請注意,任務最適合 I/O 綁定工作。 如果您可以發布在長期運行過程中究竟做了什么,那么我可以改進答案以最適合您的用例。

一件重要的事情是尊重傳遞給 RunAsync 方法的取消令牌,因為它表明服務即將停止。 它讓您有機會優雅地停止工作。 文檔

確保傳遞給 RunAsync(CancellationToken) 的 cancelToken 得到兌現,一旦發出信號, RunAsync(CancellationToken) 就會盡快正常退出。 請注意,如果 RunAsync(CancellationToken) 完成了它的預期工作,它不需要等待 cancelToken 發出信號並且可以優雅地返回。

正如您在我的代碼中看到的,我將CancellationToken傳遞給子方法,以便它們可以對可能的取消做出反應。 在您的情況下,由於無限循環,將會取消。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM