簡體   English   中英

如何將此C#工作線程代碼與主線程中的共享數據變量分離?

[英]How can I decouple this C# worker thread code from the main thread for shared data variables?

為了更好的代碼可讀性,我怎么能修改下面的代碼呢?

a)將“workThreadMethod()”移動到它自己的類中

b)此工作線程類中沒有任何代碼引用主“Program”類的靜態變量

c)以上是主要的兩個要求,但是我希望作為一個副作用,這將確保為了可測試性,工作者線程類方法將更容易測試並且理想地適合通過IOC進行測試(例如Ninject)概念[如果這沒有意義,那么為了問題的目的忽略這一點]

我不確定要解決的主要挑戰是如何處理原始線程和新線程之間的兩個不同的共享變量(其中一個是新線程添加的ConcurrentQueue,另一個是原始線程的bool變量)線程用於指示新線程何時停止)

using System.Collections.Concurrent;
using System.Diagnostics;
using System.Threading;

namespace TestConsoleApp
{
    class Program
    {
        // Main Thread uses to indicate to New Thread to stop
        private static bool _shouldStop = false;

        // New Thread uses to pass back result to Main Thread
        private static long _results = 0;

        // Main Thread passes ongoing updates to New Thread via this queue
        private static ConcurrentQueue<long> _workQueue = new ConcurrentQueue<long>();

        static void Main(string[] args)
        {
            var p = new Program();
            p.TestThreads();
        }

        public void TestThreads()
        {
            _shouldStop = false;
            var workThread = new Thread(workThreadMethod);
            workThread.Start();

            for (int i = 0; i < 100; i++)
            {
                _workQueue.Enqueue(i);   // Add test data to queue
                Debug.WriteLine("Queue  : " + i);
                Thread.Sleep(10);
            }

            Thread.Sleep(5000);

            _shouldStop = true;
            workThread.Join();
            Debug.WriteLine("Finished TestThreads.  Result = " + _results);
        }


        // Dequeuer Methods
        private void workThreadMethod()
        {
            // Update Summary
            while (!_shouldStop)
            {
                if (_workQueue.Count == 0)
                {
                    Thread.Sleep(10);
                }
                else
                {
                    long currentValue;
                    bool worked = _workQueue.TryDequeue(out currentValue);
                    if (worked)
                    {
                        _results += currentValue;
                        Debug.WriteLine("DeQueue: " + currentValue);
                    }
                }
            }
        }
    }
}

這是一個關注點分離的練習,最初我會把這個程序分成一個work providerworker 提供者負責隊列和執行控制,而工作人員應該進行計算。 以下代碼是一個粗略的開始,但它應該讓你去。

拆分這兩個問題並使用構造函數注入已經支付了可測試性,您現在可以在不涉及Program情況下完全測試Worker

注意:考慮到您的應用程序的進一步開發,我強烈建議您查看任務並行庫 使用諸如TPL之類的庫使您可以利用多核處理器,而無需處理線程分配和工作調度的復雜性。 這里討論有關TPL的更多資源。

public interface IWorkProvider
{
    bool ShouldStop { get; }
    long? GetWork();
}

public class Program : IWorkProvider
{
    // Main Thread uses to indicate to New Thread to stop
    private static bool _shouldStop = false;

    // Main Thread passes ongoing updates to New Thread via this queue
    private static ConcurrentQueue<long> _workQueue = new ConcurrentQueue<long>();

    public bool ShouldStop { get { return _shouldStop; } }

    public long? GetWork()
    {
        long currentValue;
        bool worked = _workQueue.TryDequeue(out currentValue);
        if (worked)
            return currentValue;
        return null;
    }
}

public class Worker
{
    private long _results;
    private readonly IWorkProvider _workProvider;

    public long Results { get { return _results; }}

    public Worker(IWorkProvider workProvider)
    {
        _workProvider = workProvider;
    }

    public void DoWork()
    {
        // Update Summary
        while (!_workProvider.ShouldStop)
        {
            long? work = _workProvider.GetWork();
            if (work.HasValue)
            {
                _results += work.Value;
                Debug.WriteLine("DeQueue: " + work.Value);
            }
            else
            {
                Thread.Sleep(10);
            }
        }
    }

}

暫無
暫無

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

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