DOBON.NET DOBON.NETプログラミング掲示板過去ログ

Invokeについて

  • 題名: Invokeについて
  • 著者: たく
  • 日時: 2009/12/08 14:52:49
  • ID: 25988
  • この記事の返信元:
    • (なし)
  • この記事への返信:
  • ツリーを表示
環境/言語:[VB2008]
分類:[.NET]

お世話になります。
今まで参考にさせて頂きありがとうございます。
ある程度、形になってきたのですが、どうしてもよくわからないのでよろしくお願いします。

(Form1)
Imports System.Threading
Imports System.IO.Ports

Public Class InTest

'=============================================
' 定数宣言
'=============================================
Delegate Sub Update(ByVal str As String)

:
:
:

Private Sub Switch()

Dim port As SerialPort = New SerialPort("COM1", 9600, Parity.Even, 8, StopBits.One)

Flg = 0

port.Open()
port.DtrEnable = True
port.RtsEnable = True

'通信開始コマンド送信
Dim Startreq As String = "343335320D"
port.WriteLine(Startreq)

'レスポンス確認
Dim res As String
res = ""
Try
port.ReadTimeout = g_strRS232CTimeout
res = port.ReadLine()
Catch
res = "-1"
End Try
If res <> "343334330D0A" Then

Dim logUpdateFunc As New Update(AddressOf InTestExe.updText)
InTestExe.Invoke(logUpdateFunc, New Object() {"コマンド送信エラー"})    ←

Flg = 1
port.Close()
port.Dispose()
Exit Sub
End If

port.Close()
port.Dispose()

End Sub

'Public Class End ------ InTest
End Class

(Form2)
Imports System
Imports System.Threading

Public Class InTestExe

Public Sub updText(ByVal strText As String)
Me.datagrid1.Rows.Insert(0, strText)

'Private Sub End ------ updText
'================================================
End Sub

End Class

Switchの中で通信処理を行いエラーの場合、←の部分でForm2にあるデータグリッドビューに表示しようとしました。すると”ウィンドウ ハンドルが作成される前、コントロールで Invoke または BeginInvoke を呼び出せません。”となりました。調べたところスレッドが関係していそうでInvokeを入れましたが解消されませんでした。何が問題かご教示をお願いします。
お疲れ様です。

推測ですが、
InTestExeという名前の(暗黙の)FormオブジェクトのInvokeメソッドを呼び出していて、そのFormオブジェクト自体は画面に表示されていない、ように思えます。(たく さんのコードがInTestExe型の別のFormオブジェクトを画面に表示しているのかもしれません)
お返事ありがとうございます。
しかし、申し訳ありませんが、ちょっと理解ができないです。
Invokeは使用できないということなのでしょうか?

よろしくお願いします。

> 推測ですが、
> InTestExeという名前の(暗黙の)FormオブジェクトのInvokeメソッドを呼び出していて、そのFormオブジェクト自体は画面に表示されていない、ように思えます。(たく さんのコードがInTestExe型の別のFormオブジェクトを画面に表示しているのかもしれません)
お疲れ様です。

以下のコードで試してみてください。

# 暗黙のFormインスタンスは、型名とインスタンス名が同じで非常に紛らわしく、
# うっかり間違って使ってしまうことがありますので要注意です。
# (Formに共有メンバや定数を定義しない、などの自己防衛をしてください)

Imports System.Threading

' Button1を配置してください
Public Class Form3

    Dim _frm4 As New Form4

    Private Sub Form3_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
        Handles Me.Load
        Me._frm4.Show()
    End Sub

    Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
        Handles Button1.Click
        ThreadPool.QueueUserWorkItem(AddressOf Me.DoWork, Nothing)
    End Sub

    ' 別スレッドで実行されるメソッド
    Private Sub DoWork(ByVal dummy As Object)
        For i As Integer = 1 To 10
            Thread.Sleep(200)
            Me._frm4.updText("データです(" + i.ToString + ")")
            ' ↓これはエラーとなる。(非常に紛らわしいが)Form4という名前の、
            ' ↓Form4型の暗黙のオブジェクト(まだ画面に表示されていない)の、
            ' ↓Invokeメソッドを呼び出しているため。
            'Form4.Invoke(New Action(Of String)(AddressOf Form4.updTextDirect), "あああ")
        Next
    End Sub
End Class

'-----------------------------------
' DataGridView1を配置してください
Public Class Form4

    Public Sub updText(ByVal strText As String)
        If Me.InvokeRequired Then
            Dim method As New Action(Of String)(AddressOf Me.updText)
            Me.Invoke(method, strText)
        Else
            Me.DataGridView1.Rows.Insert(0, strText)
        End If
    End Sub

    Public Sub updTextDirect(ByVal strText As String)
        Me.DataGridView1.Rows.Insert(0, strText)
    End Sub

End Class
  • 題名: Re[4]: Invokeについて
  • 著者: たく
  • 日時: 2009/12/15 9:53:28
  • ID: 26051
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
大変返事が遅くなって申し訳ありません。
下記をためさせていただきます。
ありがとうございました。

■No26006に返信(H.K.R.さんの記事)
> お疲れ様です。
>
> 以下のコードで試してみてください。
>
> # 暗黙のFormインスタンスは、型名とインスタンス名が同じで非常に紛らわしく、
> # うっかり間違って使ってしまうことがありますので要注意です。
> # (Formに共有メンバや定数を定義しない、などの自己防衛をしてください)
>
> Imports System.Threading
>
> ' Button1を配置してください
> Public Class Form3
>
> Dim _frm4 As New Form4
>
> Private Sub Form3_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
> Handles Me.Load
> Me._frm4.Show()
> End Sub
>
> Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) _
> Handles Button1.Click
> ThreadPool.QueueUserWorkItem(AddressOf Me.DoWork, Nothing)
> End Sub
>
> ' 別スレッドで実行されるメソッド
> Private Sub DoWork(ByVal dummy As Object)
> For i As Integer = 1 To 10
> Thread.Sleep(200)
> Me._frm4.updText("データです(" + i.ToString + ")")
> ' ↓これはエラーとなる。(非常に紛らわしいが)Form4という名前の、
> ' ↓Form4型の暗黙のオブジェクト(まだ画面に表示されていない)の、
> ' ↓Invokeメソッドを呼び出しているため。
> 'Form4.Invoke(New Action(Of String)(AddressOf Form4.updTextDirect), "あああ")
> Next
> End Sub
> End Class
>
> '-----------------------------------
> ' DataGridView1を配置してください
> Public Class Form4
>
> Public Sub updText(ByVal strText As String)
> If Me.InvokeRequired Then
> Dim method As New Action(Of String)(AddressOf Me.updText)
> Me.Invoke(method, strText)
> Else
> Me.DataGridView1.Rows.Insert(0, strText)
> End If
> End Sub
>
> Public Sub updTextDirect(ByVal strText As String)
> Me.DataGridView1.Rows.Insert(0, strText)
> End Sub
>
> End Class
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板