StackBufferがスタックセーフではなく、複数のスレッドからアクセス(読み書き)されたときにロックされるべきである:here、 here,here。 StringBuilderのインスタンスをロックする方法、特に追加するロックの数と場所については不明です。StringBuilderが正しくロックされてArgumentOutOfRangeExceptionがスローされないようにする方法
私は、次のコード(スニペット-ED)を持っている:
class MemoryTracker
{
private Process extProc { get; set; }
private StringBuilder sb { get; set; }
internal int trackByIP(string ip)
{
...
...
sb = new StringBuilder();
extProc.OutputDataReceived += new DataReceivedEventHandler((s, e) => sb.Append(e.Data + "\n"));
extProc.ErrorDataReceived += new DataReceivedEventHandler((s, e) => sb.Append(e.Data + "\n"));
extProc.Start();
extProc.PriorityClass = ProcessPriorityClass.RealTime;
...
...
}
string getDataWStartEndPttrn(StringBuilder data, string strPttr, string endPttr, string extendedTerminator)
{
string s = data.ToString(); // <-- THROWS ArgumentOutOfRangeException
int si = getStartIdx(s, strPttr, patternDiff(strPttr, endPttr));
int se = getEndIdx(s, endPttr, patternDiff(endPttr, strPttr));
if (se >= 0 && si >= 0)
{
string s1 = s.Substring(si, se - si);
string sTMP = s.Substring(se);
string s2 = s.Substring(se, sTMP.IndexOf(extendedTerminator));
return s1 + s2;
}
return "";
}
は、私はまだ同じエラーがスロー参照ロックを置きました。
class MemoryTracker
{
private Process extProc { get; set; }
private StringBuilder sb { get; set; }
private Object thisLock = new Object();
string getDataWStartEndPttrn(StringBuilder data, string strPttr, string endPttr, string extendedTerminator)
{
lock (thisLock)
{
string s = data.ToString() ; // <-- STILL THROWS ArgumentOutOfRangeException
}
...
...
QUESTION:どのように私は正しくロック/ロックをどこに配置するかについて考えますか?そこで私は、明示的にスレッドを作成しない場所ではありませんので、私はそれではなく、現在のそれを使用StringBuilderの周りスレッドセーフラッパーを作成StringBuilder.toString();
また、2つの 'sb.Append'文をロックする必要があります。 – Evk
これは、ロックの間違った使用です。あなたは特定のオブジェクトの使用の周りにロックします。この場合、文字列ビルダーをロックする必要があります。文字列ビルダーをパラメータとして渡しているように見えます。これは、ロックが別のスレッドによってアクセスされないようにすることを意味します。 (通常はsbの内容を変更するもの) – Hack
ありがとう、私の考えは、おそらくappend()と.toString()の両方の呼び出しをロックするべきだったということでした。しかし、おそらく1つで十分です(追加のために)? –