私はOctet
クラスを持っています。これは8つのサンプルを "パッケージ化"して前方に送ります。新しいサンプルを追加し、すでに一杯かどうかを確認し、Octet
の8つの値から構築されたFrame
データ構造を抽出する方法があります。プロパティがメソッド呼び出しの間で変更されているようですが、コードを変更する予定はありません
Octet
クラスは、「まだ完全ではないため抽出できません」と「既に完全なためにサンプルを追加できません」という2種類の例外をスローします。そのためには、クライアントコードはAdd
を呼び出す前にいっぱいになっているかどうかをチェックして、すぐにフルに抽出し、リセットする必要があります。
問題は次のとおりです。クライアントクラス(Octet
を使用している唯一のクライアントクラス)が、スローする操作の前に正しくチェックを実行しているように見えますが、エラー状態が発生しているにもかかわらず、ヒット。さらに悪いことに、デバッガがブレークしたときに値をチェックすると、正しい、つまり例外がスローされるべきではありません。
public class Client
{
private Octet _octet = new Octet();
void ProcessNewSamples(IEnumerable<int> newSamples)
{
foreach (int sample in newSamples)
{
if (!_octet.IsFull)
{
_octet.Add(sample);
}
if (_octet.IsFull)
{
var frame = _octet.ExtractFrame();
this.SendElsewhere(frame);
_octet.Reset();
}
}
}
}
public class Octet
{
const int ARRAY_SIZE = 8;
int[] _samples = new int[ARRAY_SIZE];
int _index = 0;
public bool IsFull { get { return _index >= 8; } }
public void Add(int sample)
{
if (IsFull)
{
throw new InvalidOperationException();
}
else
_samples[_index++] = sample;
}
public Frame<int> ExtractFrame()
{
if (!IsFull)
throw new InvalidOperationException();
else
return new Frame<int>(_samples);
}
public void Reset()
{
_samples = new int[ARRAY_SIZE];
_index = 0;
}
}
はProcessNewSamples'が複数から呼び出さ 'ですスレッド?その場合は、関数のオクテットへのアクセスをロックする必要があります。 – Nico
@heinzbeinz [OK]を、私は、コードが実行されているタスクが誤って複数回呼び出されていることがわかりました。まあ、これはクライアントコードの不具合であると確信しており、修正するつもりです。しかし、「ロック」戦略に関しては、回答として投稿することはできますか?私はロックを入れるのに最適な場所がわからない。どうもありがとうございました! – heltonbiker