[seasar-dotnet:606] ガベージコレクト発生後のS2TestCase.ReadXlsWriteDbの挙動について
Masayuki TAMADA
[E-MAIL ADDRESS DELETED]
2007年 10月 12日 (金) 17:46:47 JST
初めまして。タマダと言います。
業務で利用させて貰っています。
その中でS2Unit.NETをDBに対するテストにて利用しています。
その時、テーブル数/テストケースが多い場合、ReadXlsWriteDbメソッド呼び出し時に以下の様な例外が発生する事があります。
---
項目は既に追加されています。辞書のキー: 'テーブル名' 追加されるキー: 'テーブル名'
場所 System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add)
場所 System.Collections.Hashtable.Add(Object key, Object value)
場所 Seasar.Extension.DataSets.States.CreatedState.GetSql(DataTable table)
場所 Seasar.Extension.DataSets.States.AbstractRowState.Update(IDataSource
dataSource, DataRow row, ICommandFactory commandFactory)
場所 Seasar.Extension.DataSets.Impl.SqlTableWriter.DoWrite(DataTable table)
場所 Seasar.Extension.DataSets.Impl.SqlTableWriter.Write(DataTable table)
場所 Seasar.Extension.DataSets.Impl.SqlWriter.Write(DataSet dataSet)
場所 Seasar.Extension.Unit.S2TestCase.WriteDb(DataSet dataSet)
場所 Seasar.Extension.Unit.S2TestCase.ReadXlsWriteDb(String path)
---
必ず発生する訳ではないので放置していたのですが、ちょっと気になったので
ソースレベルで追ってみました。
Seasar.Extension.DataSets.States.CreatedStateクラス中のGetSqlメソッド内で
WeakReferenceにて参照されるターゲット(SQL文字列)をHashtableにて管理されて
いますが、その再利用時の判定に問題がある気がします。
現在は
if (reference == null || !reference.IsAlive)
{
sql = CreateSql(table);
_sqlCache.Add(table, new WeakReference(sql));
}
となっています。
しかし、ガベージコレクトにてターゲットが回収済みの場合はAddメソッド呼び出し時に必ずArgumentExceptionが発生する事になります。ですので、上記は
if (reference == null)
{
sql = CreateSql(table);
_sqlCache.Add(table, new WeakReference(sql));
}
else if (!reference.IsAlive)
{
reference.Taget = CreateSql(table);
}
となるべきでは無いでしょうか?
お手数ですが、確認の程宜しくお願いします。
seasar-dotnet メーリングリストの案内