1 つのコンシューマー タスクと 1 つのプロデューサー タスクを持つ WinForms アプリがあります。私のプロデューサー タスクは定期的に Web サービスに接続し、指定された数の文字列を取得します。これらの文字列は、ある種の同時固定サイズ FIFO キューに配置する必要があります。次に、コンシューマ タスクはこれらの文字列を処理し、SMS メッセージとして送信します (メッセージごとに 1 つの文字列)。プロデューサー タスクが呼び出す SOAP 関数には、取得する文字列の数を指定するパラメーターが必要です。この数は、キューで利用可能なスペースによって決まります。したがって、キューの最大サイズが 100 文字列で、次にプロデューサーが Web サービスをポーリングするときに 60 文字列がキューにある場合、その時点でキューに収まるのはそれだけなので、40 文字列を要求する必要があります。 .
固定サイズの FIFO キューを表すために使用しているコードは次のとおりです。
public class FixedSizeQueue<T>
{
private readonly List<T> queue = new List<T>();
private readonly object syncObj = new object();
public int Size { get; private set; }
public FixedSizeQueue(int size)
{
Size = size;
}
public void Enqueue(T obj)
{
lock (syncObj)
{
queue.Insert(0, obj);
if (queue.Count > Size)
{
queue.RemoveRange(Size, queue.Count - Size);
}
}
}
public T[] Dequeue()
{
lock (syncObj)
{
var result = queue.ToArray();
queue.Clear();
return result;
}
}
public T Peek()
{
lock (syncObj)
{
var result = queue[0];
return result;
}
}
public int GetCount()
{
lock (syncObj)
{
return queue.Count;
}
}
私のプロデューサー タスクは現在、Web サービスから必要な文字列の数を指定していませんが、キュー (q.GetCount()) 内の現在の項目数を取得し、それを最大キュー サイズ。ただし、GetCount() はロックを使用しますが、GetCount() が終了するとすぐに、コンシューマー タスクがキュー内の 10 個の文字列を処理できる可能性はありませんか?つまり、実際にはキューを 100% 維持することはできません。満杯?
また、私のコンシューマ タスクは、基本的に、SMS メッセージで送信する前に、キューの最初の文字列を「覗く」必要があります。メッセージを送信できない場合は、文字列をキュー内の元の位置に残す必要があります。これを達成するために私が最初に考えたのは、キューの最初の文字列を「のぞいて」SMS メッセージで送信し、送信が成功した場合はキューから削除することです。このようにして、送信が失敗した場合でも、文字列は元の位置でキューに残ります。それは合理的に聞こえますか?