3
class MultiThreading
{
    public class ThreadClass
    {
        public string InputString { get; private set; }
        public int StartPos { get; private set; }
        public List<SearchAlgorithm.CandidateStr> completeModels;
        public List<SearchAlgorithm.CandidateStr> partialModels;

        public ThreadClass(string s, int sPos)
        {
            InputString = s;
            StartPos = sPos;
            completeModels = new List<SearchAlgorithm.CandidateStr>();
            partialModels = new List<SearchAlgorithm.CandidateStr>();
        }

        public void Run(int strandID)
        {
            Thread t = new Thread(() => this._run(strandID));
            t.Start();
        }

        private void _run(int strandID)
        {
            SearchAlgorithm.SearchInOneDirection(strandID, ref this.completeModels, ref this.partialModels);
        }

        public static void CombineResult(
            List<ThreadClass> tc,
            out List<SearchAlgorithm.CandidateStr> combinedCompleteModels,
            out List<SearchAlgorithm.CandidateStr> combinedPartialModels)
        {
            // combine the result
        }
    }
}

class Program
    {

        static void Main(string s, int strandID)
        {
            int lenCutoff = 10000;
            if (s.Length > lenCutoff)
            {
                var threads = new List<MultiThreading.ThreadClass>();
                for (int i = 0; i <= s.Length; i += lenCutoff)
                {
                    threads.Add(new MultiThreading.ThreadClass(s.Substring(i, lenCutoff), i));
                    threads[threads.Count - 1].Run(strandID);
                }


                **// How can I wait till all thread in threads list to finish?**
            }
        }
    }

私の質問は、「スレッド」リスト内のすべてのスレッドが終了するまで待ってから、CombineResult メソッドを呼び出すにはどうすればよいですか?

ありがとう

4

3 に答える 3

5

List<Thread>すべてのスレッドを記録する構造を追加できます

private List<Thread> threads = new List<Thread>();

次に、リストにスレッドを入力します

public void Run(int strandID)
{
    Thread t = new Thread(() => this._run(strandID));
    t.Start();
    threads.Add(t);
}

Join最後に、リスト内の各スレッドを呼び出すメソッドを作成できます。プログラムが永久にブロックされないように、通常はタイムアウト遅延を設定することをお勧めします (スレッドにバグがある場合)。

public void WaitAll(List<Thread> threads, int maxWaitingTime)
{
    foreach (var thread in threads)
    {
        thread.Join(maxWaitingTime); //throws after timeout expires
    }
}


別の方法は、クラスを使用しTaskて呼び出すことですTask.WaitAll

于 2012-07-26T16:30:08.543 に答える
1

答えはすでに選択されているようSystem.Threading.Tasksですが、他のいくつかの提案に従って、ソリューションの作成をすでに開始していました。LINQを使用するのではなく、元のコードの構造を可能な限り一致させるようにしました。

class SearchClass
{
    public String InputString { get; private set; }
    public int StartPos { get; private set; }
    public List<string> completeModels;
    public List<string> partialModels;

    public SearchClass(string s, int sPos)
    {
        InputString = s;
        StartPos = sPos;
        completeModels = new List<string>();
        partialModels = new List<string>();
    }

    public void Run(int strandID)
    {
        // SearchAlgorithm.SearchInOneDirection(...);
    }

    // public static void CombineResult(...){ };
}

class Program
{
    static void Main(string s, int strandID)
    {      
        int lenCutoff = 10000;

        if (s.Length > lenCutoff)
        {
            var searches = new List<SearchClass>();
            var tasks = new List<System.Threading.Tasks.Task>();

            for (int i = 0; i < s.Length; i += lenCutoff)
            {
                SearchClass newSearch = new SearchClass(s.Substring(i, lenCutoff), i);
                searches.Add(newSearch);
                tasks.Add(System.Threading.Tasks.Task.Factory.StartNew(()=>newSearch.Run(strandID)));
            }

            System.Threading.Tasks.Task.WaitAll(tasks.ToArray());

            // Combine the result
        }
    }
}
于 2012-07-26T19:16:01.893 に答える
1

スレッドに参加するThreadClass手段を公開する:

    private Thread nativeThread;
    public void Run(int strandID)
    {
        nativeThread = new Thread(() => this._run(strandID));
        nativeThread.Start();
    }

    public void Join()
    {
        nativeThread.Join();
    }

そして、ThreadClass.Joinそれらを開始した後、各スレッドで使用します。

    var threads = new List<ThreadClass>();
    for (int i = 0; i <= s.Length; i += lenCutoff)
    {
        threads.Add(new ThreadClass(s.Substring(i, lenCutoff), i));
        threads[threads.Count - 1].Run(strandID);
    }

    // Waits for each thread to finish in succession
    threads.ForEach(t => t.Join());

または、あなたを捨ててThreadClass楽しんでくださいSystem.Threading.Tasks

// e.g. class Models { Complete; Partial; }
// private Models Search(string source, int offset, int length, int ID)
var tasks = new List<Task<Models>>(
    from x in Enumerable.Range(0, s.Length / lenCutoff)
    select Task.Factory.StartNew<Models>(
        () => Search(s, x, lenCutoff, strandID));
);

// private Models CombineResults(IEnumerable<Models> results)
var combine = Task.Factory.ContinueWhenAll<Models>(
    tasks.ToArray(),
    ts => CombineResults(ts.Select(t => t.Result)));

combine.Wait();

Models combinedModels = combine.Result;
于 2012-07-26T16:29:51.367 に答える