问题
Basically I have a blockingcollection in my windows service application, each time I want to add 4 items to the collection then processing it.
The first round is okay, but the second round failed. The error is
The BlockingCollection has been marked as complete with regards to additions.
My code:
public static BlockingCollection<Tuple<ChannelResource, string>> bc = new BlockingCollection<Tuple<ChannelResource, string>>();
public static List<string> list = new List<string>(); // then add 100 items to it.
The main application code:
ProcessCall pc = new ProcessCall(OvrTelephonyServer, bc);
while (true)
{
ThreadEvent.WaitOne(waitingTime, false);
lock (SyncVar)
{
Console.WriteLine("Block begin");
for (int i = 0; i < 4; i++)
{
var firstItem = list.FirstOrDefault();
ChannelResource cr = OvrTelephonyServer.GetChannel();
bc.TryAdd(Tuple.Create(cr, firstItem));
list.Remove(firstItem);
}
bc.CompleteAdding();
pc.SimultaneousCall();
Console.WriteLine("Blocking end");
if (ThreadState != State.Running) break;
}
}
I realized that there was a code bc.CompleteAdding();
to block the further additions. So I commented out it, but it would not go to the second round block. It didn't reach the code Console.WriteLine("Blocking end");
It was same as my old thread.
回答1:
By the hint from TaW, I recreated the collection in each iteration.
Each iteration has its own CompleteAdding()
.
lock (SyncVar)
{
bc = new BlockingCollection<Tuple<ChannelResource, string>>();
ProcessCall pc = new ProcessCall(OvrTelephonyServer, bc);
if (list.Count > 0)
{
Console.WriteLine("Block begin");
for (int i = 0; i < 4; i++)
{
if (list.Count > 0)
{
var firstItem = list.FirstOrDefault();
ChannelResource cr = OvrTelephonyServer.GetChannel();
bc.TryAdd(Tuple.Create(cr, firstItem));
list.Remove(firstItem);
}
}
bc.CompleteAdding();
pc.SimultaneousCall();
Console.WriteLine("Blocking end");
}
if (ThreadState != State.Running) break;
}
来源:https://stackoverflow.com/questions/25204958/cant-add-items-to-the-collection-in-the-second-round