Re: .net 2.0 : looking for a "best practice" for multi threading jobs
- From: "Steve B." <steve_beauge@xxxxxxxxxxxx>
- Date: Mon, 26 Feb 2007 16:47:26 +0100
Hi again,
I'm getting troubles in implementing the producer/consumer pattern for
multiple parralel threads...
Here where I am (a project class)... the code is simplified for better
read...
In some conditions, all threads are "blocked" in the GetNectAction() method
waiting in the Monitor.WaitOne method...
Do you have any idea what is wrong ?
Thanks,
Steve
public class Project
{
#region Properties
private int m_numberOfThreads;
private object m_numberOfThreadsLockObject = new object();
public int NumberOfThreads
{
get
{
lock (m_numberOfThreadsLockObject)
{
return m_numberOfThreads;
}
}
}
private int m_runningThreads = 0;
private object m_runningThreadsLockObject = new object();
public int RunningThreads
{
get
{
lock (m_runningThreadsLockObject)
{
return m_runningThreads;
}
}
}
private Exporter m_exporter;
public Exporter Exporter
{
get { return m_exporter; }
}
#region Cancellable worker
private readonly object m_stoppingLockObject = new object();
private bool m_stopping;
public bool Stopping
{
get
{
lock (m_stoppingLockObject)
{
return m_stopping;
}
}
}
private bool m_stopped;
public bool Stopped
{
get
{
lock (m_stoppingLockObject)
{
return m_stopped;
}
}
}
private void SetStopped()
{
Debug.WriteLine("Fin des threads par " + Thread.CurrentThread.Name);
lock (m_numberOfThreadsLockObject)
{
this.m_stopped = true;
}
}
#endregion
private Queue<Action> m_actions;
private object m_actionsLockObject = new object();
protected Queue<Action> Actions
{
get
{
lock (m_actions)
{
return m_actions;
}
}
}
#endregion
public Project(
int numberOfThreads
)
{
this.m_numberOfThreads = numberOfThreads;
this.m_actions = new Queue<Action>();
}
public void Execute()
{
for (int i = 0; i < m_numberOfThreads; i++)
{
lock (m_runningThreadsLockObject)
{
ThreadStart ts = new ThreadStart(WorkerMethod);
Thread t = new Thread(ts);
t.Name = "Thread N°" + i.ToString();
t.Start();
m_runningThreads++;
}
}
AddAction(new DownloadAction(
new Uri("http://myserver/app/rootfile")
));
}
}
public void AddAction(Action a)
{
Debug.WriteLine("AddAction dans thread " + Thread.CurrentThread.Name);
lock (m_actionsLockObject)
{
Actions.Enqueue(a);
Debug.WriteLine("Monitor.Pulse " + Thread.CurrentThread.Name);
Monitor.Pulse(m_actionsLockObject);
}
}
private Action GetNextAction()
{
lock (m_actionsLockObject)
{
Monitor.Wait(this.m_actionsLockObject);
return Actions.Dequeue();
}
}
private void WorkerMethod()
{
Debug.WriteLine("WorkerMethod dans thread " + Thread.CurrentThread.Name);
Action a;
while (!Stopping && (a = GetNextAction()) != null)
{
a.Execute();
}
lock (m_runningThreadsLockObject)
{
if (--m_runningThreads == 0)
{
SetStopped();
}
}
Debug.WriteLine("Fin du thread " + Thread.CurrentThread.Name);
}
public void Stop()
{
lock (m_actionsLockObject)
{
Monitor.PulseAll(m_actionsLockObject);
}
Debug.WriteLine("Stop dans thread " + Thread.CurrentThread.Name);
lock (m_stoppingLockObject)
{
this.m_stopping = true;
}
}
}
"Michael Nemtsev" <nemtsev@xxxxxxx> a écrit dans le message de news:
1799a79b3d745c8c925a4aeaed6ee@xxxxxxxxxxxxxxxxxxxxxxx
Hello Steve B.,
S> I'm building an application that follow this scenario.
S> 1. Download a file on a server with http
S> 2. Analyse this file and extract other files in one of the section of
S> the
S> file (like dependent files)
S> 3. Foreach found files, repeat the whole process.
S> The question is : how can I quickly and correctly design my code to
S> have my winform dynamic, and the pool of working threads?
S> My first reflexion was to store the whole data in a DataSet (easy
S> databinding) which can be flat (only on DataTable required).
so, you keep serialized objects?! why not to just save files on your
drive?
S> I also created an abstract class "BaseAction" that is inherited by
S> two classes : "DownloadAction" and "AnalyseAction".
S> My process object defines a Queue<Action> where I add all required
S> actions.
S> But I'm confused for the next steps... how can I have multiples
S> trheads that can "Dequeue" actions? moreover, I don't know how to
manage the
S> multiples threeads since sometimes I'll have only one item in te queue,
and
S> this item can add new items...
You can use ThreadPool class (standard .net) or Produce/consummer pattern
http://www.yoda.arachsys.com/csharp/threads/threadpool.shtml
http://groups.google.ru/group/microsoft.public.dotnet.framework/browse_thread/thread/a33378c87b856678/abc251c95cbac487
The idea is that you can dequeue your files and each tread will analyze
your files dequeuing them
---
WBR, Michael Nemtsev [C# MVP]. My blog: http://spaces.live.com/laflour
Team blog: http://devkids.blogspot.com/
"The greatest danger for most of us is not that our aim is too high and we
miss it, but that it is too low and we reach it" (c) Michelangelo
.
- Follow-Ups:
- Re: .net 2.0 : looking for a "best practice" for multi threading jobs
- From: Jon Skeet [C# MVP]
- Re: .net 2.0 : looking for a "best practice" for multi threading jobs
- References:
- .net 2.0 : looking for a "best practice" for multi threading jobs
- From: Steve B.
- Re: .net 2.0 : looking for a "best practice" for multi threading jobs
- From: Michael Nemtsev
- .net 2.0 : looking for a "best practice" for multi threading jobs
- Prev by Date: ClickOnce and application command line parameters
- Next by Date: Re: VS 2005 on Windows Vista Business
- Previous by thread: Re: .net 2.0 : looking for a "best practice" for multi threading jobs
- Next by thread: Re: .net 2.0 : looking for a "best practice" for multi threading jobs
- Index(es):
Relevant Pages
|