I have an application (.Net 3.5) which c开发者_高级运维reates threads to write something to the database so that the GUI does not block. All created threads are added to a list, so that I can wait (Thread.Join) for each thread when the application is closed (maybe not all threads are finished when the application is closed, so the app must wait for them). Because of the list I get some serious problems if there are too many threads created (OutOfMemoryException). I tried removing finished threads from the list, but somehow that didn't work. Are there better ways to manage a list of threads, so I can remove them once they are finished?
Edit: It seems that fixed it (called whenever a thread is added):
lock (m_threadLock)
{
m_threads.RemoveAll(x => x.ThreadState == ThreadState.Stopped);
}
How about System.Threading.ThreadPool and SetMaxThreads plus QueueUserWorkItem?
http://msdn.microsoft.com/en-US/library/system.threading.threadpool%28v=VS.80%29.aspx
You cannot keep on creating new threads while keeping a hold on the old ones, you'll run out of memory.
I tried removing finished threads from the list, but somehow that didn't work.
That is the right path, why didn't it work?
- Add code to your thread-methods to signal completion (maybe remove themselves from the list).
- Look for a custom ThreadPool. There are several implementations published. You can use a simple one and control Background=false and other details.
Not sure if this is what you want, but how about something like this?
Action foo = () =>
{
Thread.Sleep(1000);
};
var handles = new List<WaitHandle>();
for (int i = 0; i < 10; i++)
{
var result = foo.BeginInvoke(r =>
{
foo.EndInvoke(r);
}, null);
handles.Add(result.AsyncWaitHandle);
}
WaitHandle.WaitAll(handles.ToArray());
OutOfMemoryException
doesn't seem like the sort of thing that would be caused by the list of threads - more likely it's because of the threads themselves, ie. you are creating too many of them. You need to re-use existing ones and wait for them to become available if there are too many already. This is exactly what a thread pool does. If the built-in .NET one doesn't support waiting for the threads then you'll just have to find a third-party implementation or, worst come to worst, write your own - possibly using the built-in one as a guide.
Use a more advanced ThreadPool
, like this one: http://www.codeproject.com/KB/threads/smartthreadpool.aspx . It allows you to cancel work items or wait for all work items to complete.
精彩评论