これからの季節に親子でハイキング! >>

VB.NETにおいて、2つのプロセスを起動し、その間のデータの受け渡しを行いたいのですが、
ファイルでは速度が遅すぎて、別の手法を探しています。なるべく簡単で実装できる方法を知りたい
です。ちなみに受け渡すデータのサイズですが、数十バイト程度です。よろしくお願いいたします。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

>度々の回答ありがとうございます。

「プロセス間通信のほうが遅い」
>とのことですが、具体的な実例などありますでしょうか?

なぜ遅いか?考えればすぐわかると思いますが。
単純なものは”速い”、複雑なものは”遅い”です。

最初の回答で書いたurlの方法が.NETでのまっとうなプロセス間通信の方法だと思います。
が、通信を行う双方のアプリを不正なアクセスから保護するために、何層にも処理の階層(レイヤー)が分かれて、それぞれに手順が定められています。

そんな複雑なことをやるよりは、単純な処理であるファイルの方が速いのはすぐに理解できますよね。#2に書いたとおり、キャッシュに乗ったらほとんどオンメモリでの処理です。

というか、テンポラリ用に、明示的にメモリ上にファイルを作ることだって不可能ではありません。


>>というか、速度を求めるのに今のWindowsで.NETを選択してる時点で間違ってるような・・・

>また、VB.NETを使用している理由ですが、現在および将来
>において、入手が可能な開発環境であるということです。

うーん、なぜ処理速度をそこまで求めるのでしたらCやC++ではないのでしょうか?という意味だったんですけど。
開発環境の入手性でしたらVC++.NETなら変わりませんが。

今のWindowsでは、.NET Frameworkは階層的にWindowsAPIの上にのっているだけです。つまり、余分なオーバーヘッドたっぷりです。

ただし、次期OSでは階層が逆になるので.NETの方が速くなる可能性もありますが。

ちなみに、一番単純で速いプロセス間通信は、DLLを使った共有メモリだと思います。ただし、.NETを使うんでしたら実現できませんが。
http://www.cisnet.or.jp/home/tsuneoka/win32sub/3 …

参考URL:http://www.cisnet.or.jp/home/tsuneoka/win32sub/3 …
    • good
    • 0

>この処理が数回なら全く問題ではないのです


が、数百回となると100ミリ秒でも問題となってきます。

うーん、単純に回数を掛けても意味が無いかと。
特にファイルなんて、OSによるキャッシュがバリバリ効きます。
ちゃんとした手順を踏んだプロセス間通信よりよっぽど速いと思います。

ところで排他や同期は考えないんですか?
プロセス間通信のオーバーヘッドよりこういうことのほうがよっぽど時間がかかることだと思うんですが。

というか、速度を求めるのに今のWindowsで.NETを選択してる時点で間違ってるような・・・

この回答への補足

度々の回答ありがとうございます。「プロセス間通信のほうが遅い」
とのことですが、具体的な実例などありますでしょうか?「業務」
なので、抽象的な「遅いと思う」では納得させることができないので、
具体的な内容があれば、それが知りたいです。

また、VB.NETを使用している理由ですが、現在および将来
において、入手が可能な開発環境であるということです。

補足日時:2005/06/03 21:37
    • good
    • 0

数十倍とのデータを受け渡すのに、ファイルでは遅いってのが良くわかりませんが。

FDか何かと勘違いしてませんか?

で、
.NET プロセス間通信
こんなキーワードで検索すれば、いろいろと出てきますが。
Googleの結果の2番目はこれ
http://www.microsoft.com/japan/msdn/thisweek/ste …



あとは、.NETで準備してるような方法で満足できないんでしたら、
1.WindowsAPIを使ってファイルマッピングを使う
2.WM_COPYDATAを使って別プロセスのウィンドウにメッセージとして送る。
3.WindowsAPIを使ってパイプ
ですかね。


ですかね。

この回答への補足

「遅い」というのが客観的な表現ではなかったため、誤解をされているようです。
簡単な実験プログラムで試験したところ、ファイルでデータの受け渡しを行うのに
かかる時間は約100ミリ秒でした。この処理が数回なら全く問題ではないのです
が、数百回となると100ミリ秒でも問題となってきます。最低でも5倍、できれ
ば10倍以上のスピードアップが必要なのです。また、Googleでの検索で出てくる
内容についても、具体的な実装には少々使えなさそうな感じがします。

補足日時:2005/06/02 21:08
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QVB.NETのSendMessageを教えてください

SendMessageというAPIを試しているのですが、まず試しに
Button2.Text = "test"
と同じ結果をSendMessageでやってみたいのですが
下のようにしてみたのですが、変更になりませんでした。
どのようにすれば良いかご教授頂ければ幸いです。よろしくお願致します。

Private Declare Function SendMessage Lib "user32"
Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As String) As Integer

Private Const WM_SETTEXT As Integer = &HC

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim h As Integer
h = Me.Button2.Handle.ToInt32
SendMessage(h, WM_SETTEXT, 0&, "test")
End Sub

VB.NET2003
FrameWork1.1
WindowsXP-PRO(SP2)
です。

SendMessageというAPIを試しているのですが、まず試しに
Button2.Text = "test"
と同じ結果をSendMessageでやってみたいのですが
下のようにしてみたのですが、変更になりませんでした。
どのようにすれば良いかご教授頂ければ幸いです。よろしくお願致します。

Private Declare Function SendMessage Lib "user32"
Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As String) As Integer

Private Const WM_SETTEXT As Integer = &HC

...続きを読む

Aベストアンサー

ボタンの場合はうまく行かないようです

LabelやTextBoxやComboBoxなどはこの方法で変更出来るようです
ただし API呼び出しの後でコントロールのRefreshメソッドなどを呼び出して描画を更新しないといけないようです

CheckBox、RadioButton、Button、ListBoxは変更出来ませんでした

SendMessageのAPI宣言は
  Declare Ansi Function SendMessage Lib "user32" Alias "SendMessageA" _
    (ByVal hWnd As IntPtr, ByVal wMsg As Integer, _
      ByVal wParam As Integer, _
      <MarshalAsAttribute(UnmanagedType.AsAny)> ByVal lParam As Object) As Integer
といった具合の方がより実情に合うかと思います

Q共有メモリの使い方について

開発環境:Win2000 SP4 VB6.0 SP5

共有メモリを使用して、別プロセスとデータの受け渡しを
したいと思っております。
色々調べた結果、CreateFileMappingを使用するまでは、
理解できたのですが、受け渡すデータについて困っています。

受け取る際のデータの形式が
Public Type typXYData
xx(20000) As Long
yy(20000) As Long
End Type

のユーザー定義型なっていて、64KBを越える為に宣言が
できません。
このような場合はどうやって共有メモリからデータを
受け取ったらよいのでしょうか?

解かる方ご教授お願い致します。

Aベストアンサー

まずここ読む
http://techtips.belution.com/ja/vc/0001/

んで以下のサンプルをどうぞ。
思いっきりポインタ使っています。
ってか、APIを使用するならC同様、ポインタで扱います。

サンプルは二つのプロジェクトで、両方とも
・フォーム
・標準モジュール
の構成になっています。

標準モジュールは、Project1/Project2兼用です。



'''---------------------------------------------
'''---------- Project1.Form1 ここから ----------
'''---------------------------------------------
Option Explicit

Private pProcID   As Long
Private hProcess  As Long
Private pShared   As Long
Private pSharedLen As Long


Private Const DEF_PROJECT2     As String = "c:\Project2.exe"
Private Const DEF_MAX_ARRAY     As Long = 20000
Private pLngXX(1 To DEF_MAX_ARRAY) As Long


'別アプリ起動
Private Sub Command1_Click()
  On Error GoTo PGMERR

  Dim strParam  As String
  
  '別アプリ存在チェック
  If Dir(DEF_PROJECT2) = "" Then
    MsgBox "EXEがみつからない"
    GoTo PGMEND
  End If
  
  '共有メモリに値を書き込む
  If Not memWrite(hProcess, pShared, VarPtr(pLngXX(1)), pSharedLen) Then
    Call MsgBox("共有メモリへの書き込み失敗")
    GoTo PGMEND
  End If

  'パラメータ作成(プロセスID/配列要素数/共有メモリ先頭ポインタ)
  strParam = pProcID & " " & DEF_MAX_ARRAY & " " & pShared
  
  '起動
  Call Shell(DEF_PROJECT2 & " " & strParam)
  
PGMEND:
  Exit Sub

PGMERR:
  Call MsgBox(Err.Description, vbCritical)
  GoTo PGMEND
End Sub


'ロード
Private Sub Form_Load()
  Me.Command1.Caption = "別アプリ起動"
  Me.Command1.Enabled = False
  
  'プロセスIDを取得する
  If Not GetThreadProcessId(Me.hwnd, pProcID) Then
    Call MsgBox("プロセス情報取得失敗")
    GoTo PGMEND
  End If
  
  '共有メモリオープン
  pSharedLen = (Len(pLngXX(1)) * DEF_MAX_ARRAY)
  If Not memOpen(pProcID, pSharedLen, hProcess, pShared) Then
    Call MsgBox("共有メモリ確保失敗")
    GoTo PGMEND
  End If
  
  
  'ダミーの値をセット
  Call setValues
  
  Me.Command1.Enabled = True
  
PGMEND:
End Sub

'アンロード
Private Sub Form_Unload(Cancel As Integer)
  Call memFree(hProcess, pShared)
End Sub


'ダミー値セット
Private Sub setValues()
  Dim i    As Long
  
  '適当に乱数をセット
  For i = 1 To DEF_MAX_ARRAY
    pLngXX(i) = Int(30 * Rnd)
  Next i
End Sub
'''---------------------------------------------
'''---------- Project1.Form1 ここまで ----------
'''---------------------------------------------



'''---------------------------------------------
'''---------- Project2.Form1 ここから ----------
'''---------------------------------------------
Option Explicit

Private hProcess  As Long

Private Sub Form_Load()
  Dim strCmd   As String
  Dim varWk    As Variant
  
  strCmd = Command$
  If strCmd = "" Then
    MsgBox "パラメータなし"
    End
  End If
  
  'デバッグ用リストボックスクリア
  Me.List1.Clear
  
  'パラメータ分解
  varWk = Split(strCmd, " ")
  
  '読み取りと画面反映
  Call memDataRead(CLng(varWk(0)), CLng(varWk(1)), CLng(varWk(2)))
End Sub

'読み取りと画面反映
Private Sub memDataRead(ByVal inAppID As Long, ByVal inArrayCount As Long, ByVal lngMemPointer As Long)
On Error GoTo PGMEND
  Dim lngXX()   As Long
  Dim dwSize   As Long
  Dim i      As Long
  
  '配列領域確保
  ReDim lngXX(1 To inArrayCount) As Long
  
  'メモリサイズを取得
  dwSize = Len(lngXX(1)) * inArrayCount
  
  '共有メモリ確保
  If Not procOpen(inAppID, hProcess) Then
    Call MsgBox("共有メモリ確保失敗")
    GoTo PGMEND
  End If
  
  '共有メモリから値を読み込む
  If Not memRead(hProcess, lngMemPointer, VarPtr(lngXX(1)), dwSize) Then
    Call MsgBox("共有メモリからの読み込む失敗")
    GoTo PGMEND
  End If

  'デバッグ用リストボックスへ出力
  For i = 1 To inArrayCount
    Me.List1.AddItem lngXX(i)
  Next i
PGMEND:
  Call procFree(hProcess)
  Exit Sub
PGMERR:
  Call MsgBox(Err.Description, vbCritical)
  GoTo PGMEND
End Sub
'''---------------------------------------------
'''---------- Project2.Form1 ここまで ----------
'''---------------------------------------------



'''-----------------------------------------------
'''---------- Project1.Module1 ここから ----------
'''---------- Project2.Module1 ここから ----------
'''---------- 二つのプロジェクトで必要 ----------
'''-----------------------------------------------
Option Explicit

Private Declare Function OpenProcess Lib "kernel32" ( _
  ByVal dwDesiredAccess As Long, _
  ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function VirtualAllocEx Lib "kernel32" ( _
  ByVal hProcess As Long, _
  ByVal lpAddress As Long, _
  ByVal dwSize As Long, _
  ByVal flAllocationType As Long, _
  ByVal flProtect As Long) As Long
Private Declare Function VirtualFreeEx Lib "kernel32" ( _
  ByVal hProcess As Long, _
  ByVal lpAddress As Long, _
  ByVal dwSize As Long, _
  ByVal dwFreeType As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" ( _
  ByVal hwnd As Long, _
  ByRef lpdwProcessId As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" ( _
  ByVal hObject As Long) As Long
Private Declare Function WriteProcessMemory Lib "kernel32" ( _
  ByVal hProcess As Long, _
  ByVal lpBaseAddress As Long, _
  ByVal lpBuffer As Long, _
  ByVal nSize As Long, _
  ByRef lpNumberOfBytesWritten As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" ( _
  ByVal hProcess As Long, ByVal lpBaseAddress As Long, _
  ByVal lpBuffer As Long, _
  ByVal nSize As Long, _
  ByRef lpNumberOfBytesWritten As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)


Private Const STANDARD_RIGHTS_REQUIRED As Long = &HF0000
Private Const SYNCHRONIZE        As Long = &H100000

Private Const PROCESS_TERMINATE     As Long = &H1
Private Const PROCESS_CREATE_THREAD   As Long = &H2
Private Const PROCESS_SET_SESSIONID   As Long = &H4
Private Const PROCESS_VM_OPERATION   As Long = &H8
Private Const PROCESS_VM_READ      As Long = &H10
Private Const PROCESS_VM_WRITE     As Long = &H20
Private Const PROCESS_DUP_HANDLE    As Long = &H40
Private Const PROCESS_CREATE_PROCESS  As Long = &H80
Private Const PROCESS_SET_QUOTA     As Long = &H100
Private Const PROCESS_SET_INFORMATION  As Long = &H200
Private Const PROCESS_QUERY_INFORMATION As Long = &H400
Private Const PROCESS_ALL_ACCESS    As Long = STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFF

Private Const PAGE_NOACCESS       As Long = &H1
Private Const PAGE_READONLY       As Long = &H2
Private Const PAGE_READWRITE      As Long = &H4
Private Const PAGE_WRITECOPY      As Long = &H8
Private Const PAGE_EXECUTE       As Long = &H10
Private Const PAGE_EXECUTE_READ     As Long = &H20
Private Const PAGE_EXECUTE_READWRITE  As Long = &H40
Private Const PAGE_EXECUTE_WRITECOPY  As Long = &H80
Private Const PAGE_GUARD        As Long = &H100
Private Const PAGE_NOCACHE       As Long = &H200
Private Const PAGE_WRITECOMBINE     As Long = &H400

Private Const MEM_COMMIT        As Long = &H1000
Private Const MEM_RESERVE        As Long = &H2000
Private Const MEM_DECOMMIT       As Long = &H4000
Private Const MEM_RELEASE        As Long = &H8000
Private Const MEM_FREE         As Long = &H10000
Private Const MEM_PRIVATE        As Long = &H20000
Private Const MEM_MAPPED        As Long = &H40000
Private Const MEM_RESET         As Long = &H80000
Private Const MEM_TOP_DOWN       As Long = &H100000
Private Const MEM_4MB_PAGES       As Long = &H80000000

'プロセスオブジェクトのハンドルを開く
Public Function procOpen(ByVal inAppID As Long, otProc As Long) As Boolean
  otProc = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, 0, inAppID)
  If otProc = 0 Then
    GoTo PGMEND
  End If

  procOpen = True
PGMEND:
End Function

'プロセスオブジェクトのハンドルを開放する
Public Sub procFree(inProc As Long)
  Call CloseHandle(inProc)
  inProc = 0
End Sub

'共有メモリをオープン
Public Function memOpen(ByVal inAppID As Long, ByVal inSize As Long, otProc As Long, otSharedAddress As Long) As Boolean
  '共有メモリをクローズする
  Call memFree(otProc, otSharedAddress)
  
  'プロセスオブジェクトのハンドルを開く
  If Not procOpen(inAppID, otProc) Then
    GoTo PGMEND
  End If

  
  '共有メモリを開放する
  otSharedAddress = VirtualAllocEx(otProc, 0, inSize, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
  If otSharedAddress = 0 Then
    GoTo PGMEND
  End If
  
  memOpen = True
PGMEND:
  If Not memOpen Then
    Call memFree(otProc, otSharedAddress)
  End If
End Function

'共有メモリをクローズ
Public Sub memFree(inProc As Long, inSharedAddress As Long)
  'クローズ
  Call VirtualFreeEx(inProc, inSharedAddress, 0, MEM_RELEASE)
  inSharedAddress = 0
  
  'プロセスオブジェクトのハンドルを開放する
  Call procFree(inProc)
End Sub

'共有メモリ領域に書き込む
Public Function memWrite(ByVal inProc As Long, ByVal inSharedAddress As Long, ByVal inMemPnt As Long, ByVal inSize As Long, Optional otSize As Long) As Boolean
  Dim lngSts As Long
  otSize = 0
  lngSts = WriteProcessMemory(inProc, inSharedAddress, ByVal inMemPnt, inSize, otSize)
  memWrite = (lngSts <> 0)
End Function

'共有メモリ領域から読み込む
Public Function memRead(ByVal inProc As Long, ByVal inSharedAddress As Long, ByVal inMemPnt As Long, ByVal inSize As Long, Optional otSize As Long) As Boolean
  Dim lngSts As Long
  otSize = 0
  lngSts = ReadProcessMemory(inProc, inSharedAddress, ByVal inMemPnt, inSize, otSize)
  memRead = (lngSts <> 0)
End Function

'ハンドルから、プロセスIDとスロッドIDを取得する
Public Function GetThreadProcessId(ByVal inWnd As Long, Optional otProcID As Long, Optional otThred As Long) As Boolean
  otProcID = 0
  otThred = 0
  otThred = GetWindowThreadProcessId(inWnd, otProcID)
  GetThreadProcessId = (otThred <> 0)
End Function
'''-----------------------------------------------
'''---------- Project1.Module1 ここまで ----------
'''---------- Project2.Module1 ここまで ----------
'''---------- 二つのプロジェクトで必要 ----------
'''-----------------------------------------------

参考URL:http://techtips.belution.com/ja/vc/0001/

まずここ読む
http://techtips.belution.com/ja/vc/0001/

んで以下のサンプルをどうぞ。
思いっきりポインタ使っています。
ってか、APIを使用するならC同様、ポインタで扱います。

サンプルは二つのプロジェクトで、両方とも
・フォーム
・標準モジュール
の構成になっています。

標準モジュールは、Project1/Project2兼用です。



'''---------------------------------------------
'''---------- Project1.Form1 ここから ----------
'''---------------------------------------------...続きを読む

QVB.netでSendMessageを使用して電卓を閉じたい

環境:Win XP,VB.net 2003
sendmessageを使用して電卓を閉じるプログラムを作成しているのですが、どうもあと少しでうまくいかないので質問させていただきます。
Dim hfwnd As Long
hfwnd = FindWindowEx(0, 0, "SciCalc", "電卓")
If FindWindowEx(0, 0, vbNullString, "電卓") Then
MsgBox("電卓動いてます。")
Call SendMessage(hfwnd, WM_CLOSE, 0&, 0&)
end if
この時点で電卓が開いているかどうかの判定はうまくいっています。
ですが、sendmessageのところでうまくいっておらず、hfwndに取得したウインドハンドルが代入されていない?と思いGetWindowTextでタイトル取得してみたところ空白でした。電卓をSendMessageを使用して終了させるにはどのようにしたら良いのでしょうか?

Aベストアンサー

> クラス名を同じにしても電卓をいうキャプションを持っているのがcalcだけの為、結局は同じ結果になってしまうのです。

貴方のおっしゃりたい事は分かりますが・・・
でしたら、ちゃんと、同じにしたコードを提示してください。

それから、「hfwnd」の値は確認されましたか?ちゃんと「有効な値」になってますか?

> おそらく問題はifで判断している時は成功しているということは、ハンドルは正常に持ってきているので

このIf文で分かるのは、『「FindWindowEx」の結果が「True」と判断されるものである。』と言うだけであって、
『ハンドルは正常』かどうかは分からないのでは?

#全然関係ないWindowのハンドルを持ってきている可能性だってあります。
#いや、実際「GetWindowTextでタイトル取得してみたところ空白でした。」って事は、全然関係ないハンドルって事でしょうね。


「FindWindowEx」や「SendMessage」の宣言はどうしてますか?

また、
> Dim hfwnd As Long

となってますが、WindowのハンドルってIntegerの範囲なのでは・・・

#VB6までなら、Long型で良かったですが、
#VB.NETでは、型の有効範囲が変わってますのでLongだと誤動作する可能性が・・・
#特に「FindWindowEx」や「SendMessage」の宣言でLong型にしていると、
#ほぼ確実に誤動作を起こすでしょうね。

> クラス名を同じにしても電卓をいうキャプションを持っているのがcalcだけの為、結局は同じ結果になってしまうのです。

貴方のおっしゃりたい事は分かりますが・・・
でしたら、ちゃんと、同じにしたコードを提示してください。

それから、「hfwnd」の値は確認されましたか?ちゃんと「有効な値」になってますか?

> おそらく問題はifで判断している時は成功しているということは、ハンドルは正常に持ってきているので

このIf文で分かるのは、『「FindWindowEx」の結果が「True」と判断されるもので...続きを読む

QCloseとDisposeの違い

みなさまこんばんわです。よろしくお願い申し上げます。

VB.NET 2008でコーディングしています。
CloseとDisposeの違いについて教えていただきたいのです。

これらのメソッドは、開いたファイルを閉じるときなどにも使いますが、今回お尋ねするのは、フォームを閉じるとき、しかも、自ら呼び出すとき(Me.Close() と、Me.Dispose() )のみに限ったこととしてお話しさせていただきます。

たとえば、ShowDialog() で呼び出したフォームは、そのフォーム内でMe.Close() しても、プロセスは残り、たとえば、タイマーコントロールのイベントに記述していますと、それは実行され続けます。

これを防ぐために、Me.Dispose() を使います。すると、きれいにプロセスは終了し、イベントは発生しない模様です。

そこで、「フォームを閉じる」意味のMe.Close() をすべてMe.Dispose() に変えてしまいました。確実にプロセスを破棄出来ると思ったからです。Webで調べると、違いは「再利用できる、できないの違い」という答えがありましたが、それはきっと、ファイルやオブジェクトのことで、フォームの場合は、再びShowまたはShowDialogで表示させることは可能でしたので、特に問題は感じていませんでした。

ところが、アプリケーション設定で、「最後のフォームを閉じるとき」にアプリケーションがシャットダウンする設定になってるのに、シャットダウンしてくれないことが起こりました。調べてみると、Me.Dispose() が原因。Me.Close() に変えるとうまくいきました。

わけわからなくなってきました。。。

ちなみに、その残ったフォームは、スタートアップフォームであり、別のフォームからShowまたはShowDialogメソッドで呼び出したものではありません。

ここで4つの仮説を立ててみました。

1. ShowDialogで呼び出したフォームは、Me.Dispose()、Showで呼び出した、あるいは、スタートアップフォームは、Me.Close() すれば破棄できる

2. ShowDialogで呼び出したフォームは、Me.Dispose()、スタートアップフォームは、Me.Close()、Showで呼び出したフォームは、どちらでも、破棄できる

3. 呼び出し方ではなく、別の要因が存在する

4. 併記する必要がある場合がある

Me.Close()
Me.Dispose()

または、

Me.Dispose()
Me.Close()



どれが正しいのでしょうか?どなたがご存じの方がいらっしゃいましたら、ご教授いただけませんでしょうか? どうぞよろしくお願い申し上げます。ありがとうございました。

みなさまこんばんわです。よろしくお願い申し上げます。

VB.NET 2008でコーディングしています。
CloseとDisposeの違いについて教えていただきたいのです。

これらのメソッドは、開いたファイルを閉じるときなどにも使いますが、今回お尋ねするのは、フォームを閉じるとき、しかも、自ら呼び出すとき(Me.Close() と、Me.Dispose() )のみに限ったこととしてお話しさせていただきます。

たとえば、ShowDialog() で呼び出したフォームは、そのフォーム内でMe.Close() しても、プロセスは残り、たとえば、...続きを読む

Aベストアンサー

Me.Close()
Me.Dispose()
は根本的に違うものです。

formについて、Close()メソッドはフォームの表示を終了させるメソッドです。

ほかのクラスも同様。すべてのDispose()メソッドについて、これはインスタンスの破棄を明示的に行うものです。

>再利用できる、できないの違い

Dispose()はインスタンスが破棄されるため、再びコンストラクタを用いて、インスタンスを生成しないいけません。

一方Close()はインスタンスが残っているので、それを利用することができます。

>1. ところが、アプリケーション設定で、「最後のフォームを閉じるとき」にアプリケーションがシャットダウンする設定になってるのに、シャットダウンしてくれないことが起こりました。調べてみると、Me.Dispose() が原因。
Me.Close() に変えるとうまくいきました。

通常はどちらでもうまくいきます。

>2. ShowDialogで呼び出したフォームは、Me.Dispose()、スタートアップフォームは、Me.Close()、Showで呼び出したフォームは、どちらでも、破棄できる

ShowDialogの場合は、メソッド内部で、ハンドルが破棄されているため、Close()メソッドの際にDispose()メソッドが呼び出されます。

>3. 呼び出し方ではなく、別の要因が存在する

そう思います。

>4. 併記する必要がある場合がある

インスタンスを明示的に破棄したほうがよい場合は多く存在します。
Disposeが使えるメンバはIDisposableをインターフェースとして持っているメンバです。
これらのメンバは、外部とのやり取りを行うものが多くあります。
たとえばSQLClientに含まれるようなメンバです。

外部とのコネクションを確実に破棄を保障してほしいなどという場合がありますよね、このようなときに使用します。

Using構文を使用するのとまったく同じ理由になります。
正確にはUsing構文を使用できるメンバには条件があります、IDisposableをインターフェースとして持っているメンバに限るというものです。

ほかにもガーベージコレクタによるファイナライズを伴うかどうかという違いがあります。
Disposeの場合はファイナライズが同時に行われるため、使用していたメモリ空間を開放することができます。

上記のような理由により、
Me.Close()
Me.Dispose()
は両方書いたほうがよいと思います。

蛇足ですが、
Me.Dispose()
Me.Close()
はエラーになります。
Me.Dispose()により、Me本体(インスタンス)は削除されてしまいます。
存在しないMeに対してCloseメソッドを要求することはできないためです。

Me.Close()
Me.Dispose()
は根本的に違うものです。

formについて、Close()メソッドはフォームの表示を終了させるメソッドです。

ほかのクラスも同様。すべてのDispose()メソッドについて、これはインスタンスの破棄を明示的に行うものです。

>再利用できる、できないの違い

Dispose()はインスタンスが破棄されるため、再びコンストラクタを用いて、インスタンスを生成しないいけません。

一方Close()はインスタンスが残っているので、それを利用することができます。

>1. ところが、アプリ...続きを読む

Qexe間での引き値の受け取り方法

VB.net 2003を使用しています。
テキストボックス2つとコマンドボタンが1つある画面(exe)があります。コマンドボタンを押すと引き値を今作成しているプログラム(exe)に送るプログラムがあるのですが、引き値の受け取り方法がわかりません。
検索などで調べたところコマンドラインなどを使用すればよいことがわかったのですが、使用方法がよくわかりません。

http://dobon.net/vb/dotnet/programing/commandline.html
上記のサイトを参考に見ているのですが、System.Environment.CommandLineで引き値を取り出すexeを指定しているのではないのでしょうか?メッセージボックスなどで値を調べたところ引き値を受け取るexe(このコードが書いてあるexe)が指定されているみたいなのですが、引き値を取り出すexeの指定はどこで行っているのでしょうか?
ちなみにテキストボックス2つとコマンドボタンが1つある画面(exe)は他の人が作成しており、VBでは作成されていません。
どうか回答お願い致します。

VB.net 2003を使用しています。
テキストボックス2つとコマンドボタンが1つある画面(exe)があります。コマンドボタンを押すと引き値を今作成しているプログラム(exe)に送るプログラムがあるのですが、引き値の受け取り方法がわかりません。
検索などで調べたところコマンドラインなどを使用すればよいことがわかったのですが、使用方法がよくわかりません。

http://dobon.net/vb/dotnet/programing/commandline.html
上記のサイトを参考に見ているのですが、System.Environment.CommandLineで引き値を取り...続きを読む

Aベストアンサー

今作成しているプログラム(exe)で、GetCommandLineArgs を使って渡された引数を起動されたプログラムから利用できます。

>引き値を取り出すexeを指定しているのではないのでしょうか?
コマンドラインには、起動されたプログラム自体のファイル名が含まれます。

>引き値を取り出すexeの指定はどこで行っているのでしょうか?
強いて言うなら、そのプログラムを起動しようとしたプログラムでしょう。起動されるプログラムはそれ自体なので、考える必要はないと思います。

Qvb6で異なるのプロジェクト間で、値を渡したい

VB6で、以下1~3のような画面を作成したとします。
1.プロジェクトA・ログイン画面フォーム
2.プロジェクトB・照会画面フォーム
3.プロジェクトC・登録画面フォーム

まず、1を表示して、ログインして、
次に2や3の画面に、ログイン情報を渡してやりたいのですが、
どうすればよいでしょうか?
異なるプロジェクト間で値を渡せません。

Aベストアンサー

プロジェクトA,B,CをActiveX DLLとして作成すればメイン
モジュールからそれらのコンポーネントを呼ぶだけですみ
ます。
#変数の受渡しもプロパティを使用すれば可能。
プロジェクトグループにすれば、モジュール間のデータの
受渡し等の動作確認もできます。

QVB.NETで他のEXEを実行させる

VB.NETで他のEXEを実行させる以下の2つの方法が知りたいです。

1)perlのsystemのように実行完了後に制御が戻る

2)perlのexecのように実行完了後に制御が戻らない

あと、この2つの使い分けのコツ(用途)が知りたいです。

Aベストアンサー

http://jeanne.wankuma.com/tips/vb.net/process/
こちらの8番と9番をどうぞ。

使い分けですが、
実行完了を待って次の処理をする必要がある場合は、制御が戻るまで待つ、そうでないものはキックして終わり、です。

Qプロセス間通信について

VisualBasic2005にてプログラムを作ったのですが、作ったあとに別のPCにインストールして実行してみると動作しないことに気づきました。
プログラムの内容は、Aというプログラムに引数をつけて実行すると常駐プログラムBに引数の値を渡すというシンプルなものです。AとBは同じクライアントPCにて実行します。
「VB2005逆引き大全500の極意」という書籍のプロセス間通信という産プルを参考に作ったのですが、どうもHTTPでデータを渡しているらしくWEBサーバが動作していないと動作しないんです。
私のPCはPHPなども使う為Apacheが動作中です。
通常のクライアントにHTTPでの通信を受信する方法はないのでしょうか?(ApacheなどのWEBサーバをインストールしないで)
クライアントPCには.net Framework2.0がインストール済みです。
OSはWindowsXP(Home,Pro双方)
どなたか分かる方、ご教授お願いします。

Aベストアンサー

Windowsの場合、プロセス間通信としては
・ファイル
・Windowsメッセージ
・OLE
・名前付パイプ
・メールスロット
・共有メモリ
・メモリマップドファイル
・ソケット(通信)
・メッセージキュー
・イベント
・リモート処理
これで全部ではないですが、いくつもあります。
通信でどのようなデータ(サイズ、データ量、応答速度…)のやり取りを行い、2つのプロセスが同じPC、異なるPCか、更には質問とは関係ないですが、1:N、N:Nの通信、…等の条件でどの方式にするか決めます。

参考URL:http://oshiete1.goo.ne.jp/qa3173481.html,http://oshiete1.goo.ne.jp/qa1924882.html

QDataGridViewで指定したセルの値を取得

こんにちは。

VB2008のDataGridViewで指定したセルの値を取得をする方法がわかりません。
どなたか教えてください。

Aベストアンサー

こんばんは.

 Dim Data As String
 Data = Me.DataGridView(0, 2).Value
 MsgBox(Data)

みたいな感じで取れないですかね???

QDataTableから条件を満たした行を別のDatatableへコピーしたい

VC#2005とSQLServer2005ExpressEditionでWindowsアプリケーションを作成しています。

データベースの中から1つのマスタテーブルのデータを呼び出すのにTableAdapterを使ってDataTableにデータをバインドしました。
そこから条件を満たしている行をすべて抽出して同じ型のDataTableにデータをコピーしたいのです。

ですから、DataTableは2つ用意しています。1つは上記の通りデータをバインドしていますが、もう1つは宣言しただけなのでまだ空っぽの状態です。
DataTableにはカラムが3列あり、その中の1列をグループIDとしています。
条件としてはグループIDが同じであるということです。
やりたいことは条件を満たしている行をすべて抽出して空のデータテーブルにコピーすることです。

どなたかご存知の方いらっしゃれば教えてください。
よろしくお願いします。

Aベストアンサー

C#だったんですね … さほど変わりないと思いますが

お使いのコードが提示されていないのでこちらで適当な変数をでっち上げております
現在お使いのコードを支障の無い範囲で提示しましょう

//元のデータテーブルがdtSourceとすると
// テーブル構造をコピー
DataTable dt = dtSource.Clone();
DataRow r = null;
foreach( DataRow dtRow in dtSource.Select("選択するための文字列"))
{
  r = dt.NewRow();
  for( int n = 0; n < dtRow.ItemArray.Length; n++ )
  {
    r[n] = dtRow[n];
  }
  dt.Rows.Add( r );
}
といった具合になると思います

# 前回の投稿中のstSorceはdtSourceの単なるミスです


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング