- PR -

staticなDataTableに列の追加でエラー発生

1
投稿者投稿内容
まめぞう
常連さん
会議室デビュー日: 2007/02/09
投稿数: 21
投稿日時: 2008-07-28 16:48
Visual Studio 2005 Team Edition(使用言語C#)で
Windowsサービスを開発しています。

staticなDataTable変数(以下:myDataTable)をプログラムで使用していて
あるメソッドでmyDataTableに対して以下の処理を行っています。

@変数の初期化
myDataTable = new DataTable();

A変数にカラム追加
myDataTable.Columns.Add("name", typeof(System.String));
この後、複数のカラムを追加しています。

上記のAの箇所で以下のエラーがたまに発生してしまいます。
「System.ArgumentException: 項目は既に追加されています。
辞書のキー: 'name' 追加されるキー: 'name'」

このエラーの再現方法は今のところ特定できていません。
原因がわからなくて困っています。よろしくお願いします。
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2008-07-28 17:07
考えられる代表的なパターンとして、二つのスレッドが(ほぼ)同時にその処理に入り、片方が new した直後にスレッドが切り替わり、もう片方で DataTable にカラムを追加したあとで元スレッドに再度切り替わり、同じ名前のカラムを追加することになった、とか。
まめぞう
常連さん
会議室デビュー日: 2007/02/09
投稿数: 21
投稿日時: 2008-07-28 17:26
Hongliangさん ありがとうございます。

イベントの発生は、staticなSystem.Timers.Timer変数(以下:myTimer)で
制御していて
この処理(DataTableに列の追加する処理)を呼ぶ前には、
必ず新たなイベントを発生させないようにしています
myTimer.Enabled = false; //イベントを発生させない

なので二つのスレッドが同時に実行されることは
ないはずなのです。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2008-07-28 18:07
引用:

まめぞうさんの書き込み (2008-07-28 17:26) より:
イベントの発生は、staticなSystem.Timers.Timer変数(以下:myTimer)で
制御していて
この処理(DataTableに列の追加する処理)を呼ぶ前には、
必ず新たなイベントを発生させないようにしています
myTimer.Enabled = false; //イベントを発生させない


拝見した限りでは、それだと確実ではないと思います。
イベントが発生した直後に、再度「この処理を呼ぶ」ということが起こりうるのではないでしょうか?

イベントハンドラーのメソッドに入ったらすぐに lock をしたり、あるいは、
http://www.atmarkit.co.jp/fdotnet/dotnettips/374timerstimer/timerstimer.html
の解説のように SynchronizingObject プロパティーを使うというやりかたがあります。
1

スキルアップ/キャリアアップ(JOB@IT)