InvokeとDelegeteについて への返答

投稿で使用できる特殊コードの説明。(別タブで開きます。)
本名は入力しないようにしましょう。
投稿した後で削除するときに使うパスワードです。返答があった後は削除できません。
返答する人が目安にします。相手が小学生か社会人かで返答の仕方も変わります。
最初の投稿が質問の場合、質問者が解決時にチェックしてください。(以降も追加書き込み・返信は可能です。)
※「過去ログ」について書くときはその過去ログのURLも書いてください。

以下の返答は逆順(新しい順)に並んでいます。

投稿者 tecc  (社会人) 投稿日時 2010/7/29 13:46:08
推察されたようにServiceManegerにてエラーがでていました。

sg.ServiceState の内部のサービス参照用クラスのインスタンスが
変なタイミングで破棄の保証されてました。

ありがとうございました。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2010/7/28 16:42:16
> private System.Threading.Timer timer;
System.Windows.Forms.Timer では、何か都合が悪いのでしょうか?
dataGridView1 を扱うのですから、スレッドを分けないほうが良い気がしますが…。

> ★部でNullReference~が発生します。
実際には、Invoke そのものがエラーになっているのではなく、
Invoke した先でエラーが発生している物と思われます。
try ~ catch ブロック等を用いて、どの部分に問題があったのかを Trace してみてください。

> どこか間違ってたりしますか?
ServiceManeger を使わないコードとして、たとえば
//using (ServiceManeger sg = new ServiceManeger())
{
    this.dataGridView1[1, 0].Value = "sg.ServiceState";
    this.dataGridView1[1, 1].Value = "sg.ListenerState";
}
のように修正して実験してみましたが、特に問題無く画面に表示されました。

なお、dataGridView1 には特に追加設定を加えていませんが(列定義なし、DataSource 無しの状態)、
起動時に行列数を割り当てて実験しています。
private void Form1_Load(object sender, EventArgs e)
{
   dataGridView1.ColumnCount = 3;
   dataGridView1.RowCount = 3;
   stateCallback = new System.Threading.TimerCallback(WorkerStateGet);
   timer = new System.Threading.Timer(stateCallback, null, 15000, 15000);
}
投稿者 tecc  (社会人) 投稿日時 2010/7/28 14:57:59
  .NET 3.5 sp1 です。

VB.NETではないので雑談カテで書きます。

    public partial class Form1 : Form
    {
        private System.Threading.Timer timer;
        private System.Threading.TimerCallback stateCallback;
        private delegate void StateGetStartDelegete();
  
private void Form1_Load(object sender, EventArgs e)
        {
    stateCallback = new System.Threading.TimerCallback(WorkerStateGet);
            timer = new System.Threading.Timer(stateCallback, null, 15000, 15000);
}

private  void StateGetStart()
        {
            if (InvokeRequired)
            {
              ★Invoke(new StateGetStartDelegete(StateGetStart));
                return;
            }
            using (ServiceManeger sg = new ServiceManeger())
            {
                this.dataGridView1[1,0].Value = sg.ServiceState;
                this.dataGridView1[1, 1].Value = sg.ListenerState;
            }
        }

        private void WorkerStateGet(object sender)
        {
            StateGetStart();
        }
    }


こんな感じのコードで、エラーがでます。
★部でNullReference~が発生します。

以下は内容です。
「オブジェクト参照がオブジェクト インスタンスに設定されていません。」

参考ページはここです。
http://www.atmarkit.co.jp/fdotnet/dotnettips/312ctrlinvoke/ctrlinvoke.html

どこか間違ってたりしますか?