C # : 모든 스레드가 완료 될 때까지 대기
작성중인 코드에서 공통 패턴으로 실행 중입니다. 여기서 그룹의 모든 스레드가 완료 될 때까지 기다려야하며 시간 제한이 있습니다. 타임 아웃은 모든 스레드가 완료하는 데 필요한 시간 이므로 가능한 타임 아웃이 timeout * numThreads이므로 각 스레드에 대해 단순히 thread.Join (timeout)을 수행하면 작동하지 않습니다.
지금은 다음과 같은 작업을 수행합니다.
var threadFinishEvents = new List<EventWaitHandle>();
foreach (DataObject data in dataList)
{
// Create local variables for the thread delegate
var threadFinish = new EventWaitHandle(false, EventResetMode.ManualReset);
threadFinishEvents.Add(threadFinish);
var localData = (DataObject) data.Clone();
var thread = new Thread(
delegate()
{
DoThreadStuff(localData);
threadFinish.Set();
}
);
thread.Start();
}
Mutex.WaitAll(threadFinishEvents.ToArray(), timeout);
그러나 이런 종류의 경우에는 더 간단한 관용구가 있어야 할 것 같습니다.
여전히 Join 사용이 더 간단하다고 생각합니다. 예상 완료 시간 (Now + timeout)을 기록한 다음 루프에서 다음을 수행합니다.
if(!thread.Join(End-now))
throw new NotFinishedInTime();
.NET 4.0에서는 System.Threading.Tasks 작업이 훨씬 더 쉬워졌습니다. 나를 위해 안정적으로 작동하는 스핀 대기 루프가 있습니다. 모든 작업이 완료 될 때까지 메인 스레드를 차단합니다. Task.WaitAll 도 있지만 항상 저에게 효과가있는 것은 아닙니다.
for (int i = 0; i < N; i++)
{
tasks[i] = Task.Factory.StartNew(() =>
{
DoThreadStuff(localData);
});
}
while (tasks.Any(t => !t.IsCompleted)) { } //spin wait
질문이 부딪 혔으므로 계속해서 내 솔루션을 게시하겠습니다.
using (var finished = new CountdownEvent(1))
{
for (DataObject data in dataList)
{
finished.AddCount();
var localData = (DataObject)data.Clone();
var thread = new Thread(
delegate()
{
try
{
DoThreadStuff(localData);
threadFinish.Set();
}
finally
{
finished.Signal();
}
}
);
thread.Start();
}
finished.Signal();
finished.Wait(YOUR_TIMEOUT);
}
내 머리 꼭대기에서 Thread.Join (timeout) 만하고 총 제한 시간에서 참여하는 데 걸린 시간을 제거하지 않는 이유는 무엇입니까?
// pseudo-c#:
TimeSpan timeout = timeoutPerThread * threads.Count();
foreach (Thread thread in threads)
{
DateTime start = DateTime.Now;
if (!thread.Join(timeout))
throw new TimeoutException();
timeout -= (DateTime.Now - start);
}
편집 : 코드는 이제 덜 유사합니다. +4를 수정 한 답변이 정확히 동일 할 때 답변 -2를 수정하는 이유를 이해하지 못합니다.
이것은 질문에 대답하지 않지만 (시간 제한 없음), 컬렉션의 모든 스레드를 기다리는 매우 간단한 확장 메서드를 만들었습니다.
using System.Collections.Generic;
using System.Threading;
namespace Extensions
{
public static class ThreadExtension
{
public static void WaitAll(this IEnumerable<Thread> threads)
{
if(threads!=null)
{
foreach(Thread thread in threads)
{ thread.Join(); }
}
}
}
}
그런 다음 간단히 전화하십시오.
List<Thread> threads=new List<Thread>();
//Add your threads to this collection
threads.WaitAll();
This may not be an option for you, but if you can use the Parallel Extension for .NET then you could use Task
s instead of raw threads and then use Task.WaitAll()
to wait for them to complete.
I was tying to figure out how to do this but i could not get any answers from google. I know this is an old thread but here was my solution:
Use the following class:
class ThreadWaiter
{
private int _numThreads = 0;
private int _spinTime;
public ThreadWaiter(int SpinTime)
{
this._spinTime = SpinTime;
}
public void AddThreads(int numThreads)
{
_numThreads += numThreads;
}
public void RemoveThread()
{
if (_numThreads > 0)
{
_numThreads--;
}
}
public void Wait()
{
while (_numThreads != 0)
{
System.Threading.Thread.Sleep(_spinTime);
}
}
}
- Call Addthreads(int numThreads) before executing a thread(s).
- Call RemoveThread() after each one has completed.
- Use Wait() at the point that you want to wait for all the threads to complete before continuing
I read the book C# 4.0: The Complete Reference of Herbert Schildt. The author use join to give a solution :
class MyThread
{
public int Count;
public Thread Thrd;
public MyThread(string name)
{
Count = 0;
Thrd = new Thread(this.Run);
Thrd.Name = name;
Thrd.Start();
}
// Entry point of thread.
void Run()
{
Console.WriteLine(Thrd.Name + " starting.");
do
{
Thread.Sleep(500);
Console.WriteLine("In " + Thrd.Name +
", Count is " + Count);
Count++;
} while (Count < 10);
Console.WriteLine(Thrd.Name + " terminating.");
}
}
// Use Join() to wait for threads to end.
class JoinThreads
{
static void Main()
{
Console.WriteLine("Main thread starting.");
// Construct three threads.
MyThread mt1 = new MyThread("Child #1");
MyThread mt2 = new MyThread("Child #2");
MyThread mt3 = new MyThread("Child #3");
mt1.Thrd.Join();
Console.WriteLine("Child #1 joined.");
mt2.Thrd.Join();
Console.WriteLine("Child #2 joined.");
mt3.Thrd.Join();
Console.WriteLine("Child #3 joined.");
Console.WriteLine("Main thread ending.");
Console.ReadKey();
}
}
Possible solution:
var tasks = dataList
.Select(data => Task.Factory.StartNew(arg => DoThreadStuff(data), TaskContinuationOptions.LongRunning | TaskContinuationOptions.PreferFairness))
.ToArray();
var timeout = TimeSpan.FromMinutes(1);
Task.WaitAll(tasks, timeout);
Assuming dataList is the list of items and each item needs to be processed in a separate thread.
참고URL : https://stackoverflow.com/questions/263116/c-waiting-for-all-threads-to-complete
'developer tip' 카테고리의 다른 글
커밋 간 git-diff로 * 모든 * 공백 변경 무시 (0) | 2020.11.25 |
---|---|
Windows에서 원자 적 파일 이름 바꾸기 (덮어 쓰기 포함)가 가능합니까? (0) | 2020.11.25 |
나중에 열 수 있도록 Eclipse에 탭 그룹을 저장할 수 있습니까? (0) | 2020.11.25 |
ARM 컴파일 오류, 개체 파일이 아닌 실행 파일에서 사용되는 VFP 등록 (0) | 2020.11.25 |
Keras : 커널과 활동 정규화의 차이점 (0) | 2020.11.25 |