我是初学者。基于Albahari的制作人/消费者解决方案,我开发了一个代码。编码工作正常。但我对我的实现有一些疑问。
class FloodDisaterManagement :IDisposable
{
Queue<string>MedicinePack = new Queue<string>();
Thread[] volunteers;
readonly object locker = new object();
public FloodDisaterManagement(int volunteerCount)
{
volunteers = new Thread[volunteerCount];
for (int i = 0; i < volunteerCount; i++)
{
volunteers[i] = new Thread(SupplyMedicine);
volunteers[i].Start();
}
}
public void DumpMedicine(string pack)
{
lock (locker)
{
MedicinePack.Enqueue(pack);
Monitor.PulseAll(locker);
}
}
public void Dispose()
{
foreach (Thread volunteer in volunteers) DumpMedicine(null);
foreach (Thread volunteer in volunteers) volunteer.Join();
}
public void SupplyMedicine()
{
while (true)
{
string pack;
lock (locker)
{
while (MedicinePack .Count == 0) Monitor.Wait(locker);
pack= MedicinePack.Dequeue();
}
if (pack == null) return;
Console.WriteLine(pack+"is supplied");
Thread.Sleep(1000);
}
}
static void Main()
{
string[] medicinePacks = new string[]
{ "Pack1", "Pack2", "Pack3", "Pack4", "Pack5", "Pack6",
"Pack7", "Pack8", "Pack9", "Pack10"
};
using (FloodDisaterManagement q = new FloodDisaterManagement(2))
{
foreach (string pack in medicinePacks)
q.DumpMedicine(pack);
Console.WriteLine("Enqueued 10 Medicine Packs");
}
Console.WriteLine("..Medicines Distribution Completed");
Console.ReadKey(true);
}
}
问题:
public void SupplyMedicine()
{
while (true)
{
....
if (pack == null) return;
...
//Whether the control return to Main() or SomeWhere?
}
}
答案 0 :(得分:3)
1:因为using
调用 Dispose()
;这是using
。
2:关闭每个封装的资源,在这种情况下是线程(要求它们退出,然后等待它们退出)。
3:它返回给调用者;在这种情况下,调用者是Thread
,所以这干净地退出线程
或者用英语:
using
会等待所有线程退出;没有using
我们会过早关闭foreach
表示每个线程在处理完负载后退出,并等待所有线程null
被检测为“现在退出”信号,导致每个线程退出答案 1 :(得分:1)
关于3:
由于SupplyMedicine方法在一个单独的线程上运行,并且这是线程运行的第一个也是唯一的方法 - return语句只是意味着该线程完成了它的工作并且应该被终止(或者返回到线程池以防万一您正在使用线程池线程。)