C#を使用して開発しています。
開発環境は、Visual Studio Express 2017 for Windows Desktopを使用しています。
Listに格納したデータをFormクラスで参照する際に、System.NullReferenceExceptionが発生し
対処方法がわからず困っています。
- Listの状態
以下のように作りました。このListはForm側とControl側、複数のスレッドで使われます。
C#
1class CSData 2{ 3public List<CData> lstData = new List<CData>(); 4 5・・・ 6
CDataは以下のように作りました。
C#
1public struct CData 2{ 3 public string m_strName; 4 public ushort m_wData; 5 public bool[] m_bData; 6}
- 当方で試したこと
CDataが、struct型で、初期化を行っていないことが原因ではないかと思い
classに変えました。
さらに、コンストラクタを追加し、確実に初期化を行うようにしました。
C#
1public class CData 2{ 3 public string m_strName; 4 public ushort m_wData; 5 public bool[] m_bData; 6 7 public CData() 8 { 9 m_strName= ""; 10 m_wData = 0; 11 m_bData = new bool[8]; 12 for (int i = 0; i < m_bData.Length; i++) 13 { 14 m_bData[i] = false; 15 } 16 } 17}
参照時は、lockを使っていますので
lock中に他のスレッド(Control)によってListの内容を変更されることがないものと考えています。
また、例外が発生したコードは以下の通りです。
C#
1if ((m_cls.lstData != null) 2 && (m_cls.lstData.Count> nRow) 3 && (m_cls.lstData[nRow].m_bData != null)) 4{ 5 ・・・ 6
このような例外が発生する原因、疑わしいところと、対策についてご教示いただけますでしょうか。
lstDataとlstcDataがありますが、記載ミスですか?
どこでCDataのインスタンスを生成してますか?
すみません。誤記がありましたので修正しました。
CDataのインスタンスは、lstData追加時に作成しています。
Formではなく、Control側のスレッドで作成しています。
CData cData = new CData();
cData.m_strName = "xxx";
…
m_cls.lstData.Add(cData);
といったイメージです。
lockを使っているから大丈夫とのことですが、その使い方に間違いが無いことは保証できますか。例えばlstcData[nRow].m_bData != null)を評価する寸前、別のスレッドでlstcDataの要素を削除していたらNGです。そもそもlockって、何のクラスオブジェクトなのか回答者には分かりませんし。
コード全体を見ないと判断つかないのではないでしょうか。
CDataを内包するクラスCSDataがあり、
CSDataの中でListを定義しています。
CSDataはシングルトンの構成にしてあるため
どのスレッドからでも呼び出せるようにしてあります。
CSData m_cls = new CSData.GetInstance();
エラーメッセージを見ると、lstcData[nRow] が null のようです。
> CSData m_cls = new CSData.GetInstance();
既に生成済みのシングルトン用のオブジェクトを返すであろうstaticメソッドのGetInstance()の返り値に対してnew するとは?この時点で私には分からないので、回答は難しそうです。
貴方に原因がわからないなら貴方が原因だと思ってないところに原因があるのが普通です。
貴方が原因だと思っているところを抜粋しても何も解決しません。
現象が発生する最小コードを提示してください。
CSDataでlstDataはどのように定義しているのですか?
ただ
Class CSData
{
public List<CData> lstData = new List<CData>();
}
としているのであれば提示された読み込むロジック部分でロックがかかっていないのではないですか?
排他制御が正しく行われていないのではないか?という切り口で再度調べたところ
排他制御が正しく行われていなかったことが原因とわかりました。
また、シングルトンのオブジェクトを受け取る処理は誤記です。
以下が正です。
CSData m_cls = CSData.GetInstance();
回答1件
あなたの回答
tips
プレビュー