C# と VB.NET の質問掲示板
ASP.NET、C++/CLI、Java 何でもどうぞ
掲示板トップ
C# と VB.NET 入門
新規作成
利用方法
ツリー表示
トピック表示
ランキング
記事検索
過去ログ
ログ内検索
キーワードを複数指定する場合は 半角スペース で区切ってください。
検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
[返信]をクリックすると返信ページへ移動します。
キーワード
/
検索条件
/
(AND)
(OR)
検索範囲
/
(現在のログ)
(全過去ログ)
(過去ログ1)
(過去ログ2)
(過去ログ3)
(過去ログ4)
(過去ログ5)
(過去ログ6)
(過去ログ7)
(過去ログ8)
(過去ログ9)
(過去ログ10)
(過去ログ11)
(過去ログ12)
(過去ログ13)
(過去ログ14)
(過去ログ15)
(過去ログ16)
(過去ログ17)
(過去ログ18)
(過去ログ19)
(過去ログ20)
(過去ログ21)
(過去ログ22)
(過去ログ23)
(過去ログ24)
(過去ログ25)
(過去ログ26)
(過去ログ27)
(過去ログ28)
(過去ログ29)
(過去ログ30)
(過去ログ31)
(過去ログ32)
(過去ログ33)
(過去ログ34)
(過去ログ35)
(過去ログ36)
(過去ログ37)
(過去ログ38)
(過去ログ39)
(過去ログ40)
(過去ログ41)
(過去ログ42)
(過去ログ43)
(過去ログ44)
(過去ログ45)
(過去ログ46)
(過去ログ47)
(過去ログ48)
(過去ログ49)
(過去ログ50)
(過去ログ51)
(過去ログ52)
(過去ログ53)
(過去ログ54)
(過去ログ55)
(過去ログ56)
(過去ログ57)
(過去ログ58)
(過去ログ59)
(過去ログ60)
(過去ログ61)
(過去ログ62)
(過去ログ63)
(過去ログ64)
(過去ログ65)
(過去ログ66)
(過去ログ67)
(過去ログ68)
(過去ログ69)
(過去ログ70)
(過去ログ71)
(過去ログ72)
(過去ログ73)
(過去ログ74)
(過去ログ75)
(過去ログ76)
(過去ログ77)
(過去ログ78)
(過去ログ79)
(過去ログ80)
(過去ログ81)
(過去ログ82)
(過去ログ83)
(過去ログ84)
(過去ログ85)
(過去ログ86)
(過去ログ87)
(過去ログ88)
(過去ログ89)
(過去ログ90)
(過去ログ91)
(過去ログ92)
(過去ログ93)
(過去ログ94)
(過去ログ95)
(過去ログ96)
(過去ログ97)
(過去ログ98)
(過去ログ99)
(過去ログ100)
(過去ログ101)
(過去ログ102)
(過去ログ103)
(過去ログ104)
(過去ログ105)
(過去ログ106)
(過去ログ107)
(過去ログ108)
(過去ログ109)
(過去ログ110)
(過去ログ111)
(過去ログ112)
(過去ログ113)
(過去ログ114)
(過去ログ115)
(過去ログ116)
(過去ログ117)
(過去ログ118)
(過去ログ119)
(過去ログ120)
(過去ログ121)
(過去ログ122)
(過去ログ123)
(過去ログ124)
(過去ログ125)
(過去ログ126)
(過去ログ127)
(過去ログ128)
(過去ログ129)
(過去ログ130)
(過去ログ131)
(過去ログ132)
(過去ログ133)
(過去ログ134)
(過去ログ135)
(過去ログ136)
(過去ログ137)
(過去ログ138)
(過去ログ139)
(過去ログ140)
(過去ログ141)
(過去ログ142)
(過去ログ143)
(過去ログ144)
(過去ログ145)
(過去ログ146)
(過去ログ147)
(過去ログ148)
(過去ログ149)
(過去ログ150)
(過去ログ151)
(過去ログ152)
(過去ログ153)
(過去ログ154)
(過去ログ155)
(過去ログ156)
(過去ログ157)
(過去ログ158)
(過去ログ159)
(過去ログ160)
(過去ログ161)
(過去ログ162)
(過去ログ163)
(過去ログ164)
(過去ログ165)
(過去ログ166)
(過去ログ167)
(過去ログ168)
(過去ログ169)
(過去ログ170)
(過去ログ171)
(過去ログ172)
(過去ログ173)
(過去ログ174)
(過去ログ175)
(過去ログ176)
(過去ログ177)
(過去ログ178)
(過去ログ179)
強調表示
/
ON
(自動リンクOFF)
結果表示件数
/
20件
30件
40件
50件
100件
記事No検索
/
ON
大文字と小文字を区別する
No.68841 の関連記事表示
ヒット / 15件
(1-15 を表示)
<<
0
>>
■68841
WndProcの処理を止める方法
□投稿者/ kota -
(2013/11/21(Thu) 19:22:52)
分類:[.NET 全般]
2013/11/21(Thu) 20:40:04 編集(投稿者)
WndProcを使って他のアプリケーションと通信していますが、
自分のアプリケーションの中で
private void waitTimer(int millSec)
{
DateTime start = DateTime.Now;
for (; ; )
{
TimeSpan duration = DateTime.Now - start;
if ((duration.Seconds * 1000 + duration.Milliseconds) > millSec)
{
break;
}
Application.DoEvents();
Thread.Sleep(10);
}
}
というコードを使ってWaitをしていますが、Application.DoEvents()が誤動作をします。
一時的に WndProcを無効にする方法はあるでしょうか?
親記事 /過去ログ117より /
関連記事表示
削除チェック/
■68842
Re[1]: WndProcの処理を止める方法
□投稿者/ Azulean -
(2013/11/21(Thu) 22:23:50)
■
No68841
(kota さん) に返信
> Application.DoEvents()が誤動作をします。
誤動作とは何を指していますか?
理想とする動きに対して、今はそれと異なる動きをしているので「誤動作」と表現されているのでしょうけれども、正直、第三者にはそれが何かわからないのです。
> 一時的に WndProcを無効にする方法はあるでしょうか?
ウィンドウメッセージを処理したくないということでしょうか?
そうすると、画面が白くなったり、応答なしになったり、ユーザーが操作できなかったりしますが、本当にそれでよいのでしょうか。
記事No.68841 のレス /過去ログ117より /
関連記事表示
削除チェック/
■68843
Re[2]: WndProcの処理を止める方法
□投稿者/ kota -
(2013/11/22(Fri) 09:39:20)
■
No68842
(Azulean さん) に返信
誤動作はその時により若干異なるのですが(メッセージの入り方により)、
時によってタイマーのループから抜けません。
Application.DoEvents()によりメッセージループの
呼び出しが無限ループになっているように見えます。
無効にしたいとはビルド時の [Conditional("Debug")]属性のように
メッセージのフックそのものを一時的に止めたいということです。
WndProc(ref Message m)関数をコードに入れない状態になることが
理想的です。
>画面が白くなったり、応答なしになったり、ユーザーが操作できなかったりしますが
それを防ぎたいので、Application.DoEvents()を入れています。
よろしくお願いします。
記事No.68841 のレス /過去ログ117より /
関連記事表示
削除チェック/
■68844
Re[3]: WndProcの処理を止める方法
□投稿者/ Hongliang -
(2013/11/22(Fri) 11:34:27)
> WndProc(ref Message m)関数をコードに入れない状態になることが
> 理想的です。
> それを防ぎたいので、Application.DoEvents()を入れています。
矛盾してますよ。
DoEventsはWndProcの呼び出しとおよそ同義です。
WndProcが呼び出されなかったらDoEventsを呼び出す意味もありません。
旧VBではそういう手法が使われていたこともありますが(擬似マルチスレッドのためでしたっけ?)
今時ではUIスレッドで長時間の処理をしたりApplication.DoEventsを呼び出したりするのはおよそ禁じ手とされています。
タイマを使ったりスレッド処理を使ったりして、非同期で動作できるように構成してください。
記事No.68841 のレス /過去ログ117より /
関連記事表示
削除チェック/
■68859
Re[4]: WndProcの処理を止める方法
□投稿者/ よる -
(2013/11/22(Fri) 21:52:55)
> WndProcを使って他のアプリケーションと通信していますが、
> Application.DoEvents()が誤動作をします
DoEvents内ではあらゆるメッセージが処理されているはずなので、
目的の動作が(具体的に何なのかわかりませんが)すっ飛んでいるんでしょう。多分…
APIを使って特定のウィンドウメッセージだけを処理し
画面の再描画のみを行う事もできますが、お勧めしないです。
参考:
時間がかかる処理での「応答なし」を回避するには?
http://www.atmarkit.co.jp/fdotnet/dotnettips/136doevents/doevents.html
※補足
> WndProcを使って他のアプリケーションと通信
実際にやりたい事と現在の実装方法を書いた方が、適切な回答をもらえると思いますよ(丸投げ)。
記事No.68841 のレス /過去ログ117より /
関連記事表示
削除チェック/
■68860
Re[1]: WndProcの処理を止める方法
□投稿者/ Jitta -
(2013/11/22(Fri) 22:16:27)
>
■
No68841
(kota さん) に返信
> private void waitTimer(int millSec)
> {
>
> DateTime start = DateTime.Now;
> for (; ; )
> {
> TimeSpan duration = DateTime.Now - start;
> if ((duration.Seconds * 1000 + duration.Milliseconds) > millSec)
> {
> break;
> }
> Application.DoEvents();
> Thread.Sleep(10);
> }
> }
このコードが、「一定時間待つ」ということをしたいがためのコードであるなら、
タイマーで通知してもらう方が、ずっと少ないコードで管理も楽だと思います。
記事No.68841 のレス /過去ログ117より /
関連記事表示
削除チェック/
■68864
Re[2]: WndProcの処理を止める方法
□投稿者/ kota -
(2013/11/22(Fri) 23:52:57)
■
No68860
(Jitta さん) に返信
> ■
No68841
(kota さん) に返信
>
>> private void waitTimer(int millSec)
>> {
>>
>> DateTime start = DateTime.Now;
>> for (; ; )
>> {
>> TimeSpan duration = DateTime.Now - start;
>> if ((duration.Seconds * 1000 + duration.Milliseconds) > millSec)
>> {
>> break;
>> }
>> Application.DoEvents();
>> Thread.Sleep(10);
>> }
>> }
>
> このコードが、「一定時間待つ」ということをしたいがためのコードであるなら、
> タイマーで通知してもらう方が、ずっと少ないコードで管理も楽だと思います。
記事No.68841 のレス /過去ログ117より /
関連記事表示
削除チェック/
■68865
Re[3]: WndProcの処理を止める方法
□投稿者/ kota -
(2013/11/22(Fri) 23:54:41)
回答ありがとうございます。
工業用のPCにOSはXp(客指定)のOSでリアルタイムモニター
のような使い方をしています。
PCIのGPIB、96IN/48OUTのI/Oボード、A/Dボード、3軸のモーター
コントロールボード、RS−232Cのティーチングペンダント
計測用にマルチポイントシリアルRS-485が3本繋がっています。
GPIB、232C、I/O、A/Dボードはマルチスレッドタイマーで
読み込んで、メインスレッドにチェンジイベントをあげ、
RS-485は別ソフトがメッセージを投げてきます。
自作のタイマーを含めタイマーは200個ほど使っています。
計測器などは非同期でも構わないのですが、モーターコントロールは
同期が必要で、メインスレッドで処理しています。
モーターの動きを監視し目的の場所に移動するまで、メインスレッドは
ループで待ちます。
待っている間、測定器からのメッセージはSenndMessageで待たせます。
ただしI/OからのStopコマンドは受け付ける為に、Doeventで処理を
します。
この時、自分のWndProcのコールバックメソドに処理が入り込み、
抜け出さない(これは想像ですが)症状が起きます。
仕方なく現在は単にsleepを入れています。
そこで一時的にWndProcのコールバックを禁止する方法が無いものか
と質問しました。
現在システムは殆ど完成していますがI/Oの読み込みが少し遅いために、
コードを見直しています。
記事No.68841 のレス /過去ログ117より /
関連記事表示
削除チェック/
■68866
Re[4]: WndProcの処理を止める方法
□投稿者/ Azulean -
(2013/11/23(Sat) 00:04:20)
2013/11/23(Sat) 00:06:18 編集(投稿者)
■
No68865
(kota さん) に返信
> 待っている間、測定器からのメッセージはSenndMessageで待たせます。
> ただしI/OからのStopコマンドは受け付ける為に、Doeventで処理を
> します。
> この時、自分のWndProcのコールバックメソドに処理が入り込み、
> 抜け出さない(これは想像ですが)症状が起きます。
> 仕方なく現在は単にsleepを入れています。
すでに指摘のあるとおり、DoEvents を呼んだ時点でメッセージは処理されるものです。
特定のメッセージだけ遅延させるという都合のいいものはないと考えた方がよいでしょう。
(GetMessage とかを自分で呼ぶなら別でしょうけれども)
> そこで一時的にWndProcのコールバックを禁止する方法が無いものか
> と質問しました。
ウィンドウメッセージベースでの通信となっていることと、それを待たせなければならない要求・設計の時点で、UI の操作性が損なわれる許容すべきことかと思います。
SendMessage で送られてくる処理を必ず待たせないといけないのであれば、DoEvents は使わないことです。そして、その結果として応答なしと出ることも許容しなければなりません。
これが許せないであるとか、メッセージベースなのでパフォーマンスを上げられないとか、そういったことになると、完成間近であろうと抜本的な見直しが必要だと思います。
ウィンドウメッセージに頼った通信部分を見直せないかとか、ソフトを変えられないなら自作するとか。
記事No.68841 のレス /過去ログ117より /
関連記事表示
削除チェック/
■68876
Re[5]: WndProcの処理を止める方法
□投稿者/ よる -
(2013/11/23(Sat) 13:13:36)
各種信号は別スレッドで拾ってからメインスレッドへ集約されていて、
メインスレッド=モーターコントロール用のスレッド=GUIスレッドという認識で良いでしょうか?
GUI側/制御側のレスポンス双方に影響がありそうな気がします。
現状ではイベント(ウィンドウメッセージ)で各種制御をしているわけですから、DoEventの使用はかなり危険です。
GUI(メイン)スレッドと制御スレッドを分離し、制御側がイベントに依存しない様にする事が考えられます。
・各種信号について、別スレッドからメインスレッドにイベントを投げている箇所を見直す(イベントを使わない)。
→プログラム内で信号状態を保持する。(listで状態/コマンド履歴を持つときもありますが)
・モーターコントロールをメインスレッドとは別スレッドで行う。
・各種信号状態を上記モータコントロール用スレッドで使用する(スレッドセーフに扱う事)。
それと、SendMessageはPostMessageでは駄目ですか?
SendMessageでは転送先で処理が終わるまで転送元の処理がブロックされます。
処理完了を待っているのであれば、要求/要求処理完了のハンドシェイクを互いにPostMessageで行うとか。
記事No.68841 のレス /過去ログ117より /
関連記事表示
削除チェック/
■68871
Re[4]: WndProcの処理を止める方法
□投稿者/ しま -
(2013/11/23(Sat) 09:39:38)
■
No68865
(kota さん) に返信
> 回答ありがとうございます。
>
> 工業用のPCにOSはXp(客指定)のOSでリアルタイムモニター
> のような使い方をしています。
> PCIのGPIB、96IN/48OUTのI/Oボード、A/Dボード、3軸のモーター
> コントロールボード、RS−232Cのティーチングペンダント
> 計測用にマルチポイントシリアルRS-485が3本繋がっています。
>
> GPIB、232C、I/O、A/Dボードはマルチスレッドタイマーで
> 読み込んで、メインスレッドにチェンジイベントをあげ、
> RS-485は別ソフトがメッセージを投げてきます。
>
> 自作のタイマーを含めタイマーは200個ほど使っています。
> 計測器などは非同期でも構わないのですが、モーターコントロールは
> 同期が必要で、メインスレッドで処理しています。
> モーターの動きを監視し目的の場所に移動するまで、メインスレッドは
> ループで待ちます。
>
> 待っている間、測定器からのメッセージはSenndMessageで待たせます。
> ただしI/OからのStopコマンドは受け付ける為に、Doeventで処理を
> します。
> この時、自分のWndProcのコールバックメソドに処理が入り込み、
> 抜け出さない(これは想像ですが)症状が起きます。
> 仕方なく現在は単にsleepを入れています。
>
> そこで一時的にWndProcのコールバックを禁止する方法が無いものか
> と質問しました。
>
> 現在システムは殆ど完成していますがI/Oの読み込みが少し遅いために、
> コードを見直しています。
>
画面の処理がない、若しくは画面の制御が分離できるのであれば
サービスとして動かすといいかもしれません
ただ、Windows はリアルタイムOSではないので 100mS 以内に応答するといったことは必ずしも
望めないことはご存知のことと思います
ですから、高速な応答が必要な場合はプロセスでもスレッドでも自分の処理が終わったらタイムスロットをOSに
返却(自分に割当たっているタイムスロットを独占しない)することが大切です
ところで、
> 自分のWndProcのコールバックメソドに処理が入り込み、抜け出さない
とありますが、 WndProc のコールバックとはなんのことでしょうか?
分類 .NET全般 とあったので貼り付けていたコードの記述言語は C# かと思っていましたが、 C/C++ なんですか?
開発環境、動作環境については書いてください。
記事No.68841 のレス /過去ログ117より /
関連記事表示
削除チェック/
■68872
Re[5]: WndProcの処理を止める方法
□投稿者/ kota -
(2013/11/23(Sat) 10:19:47)
■
No68871
(しま さん) に返信
回答有難うございます。
言語はC#です。
コールバックと書いたのは
>>
http://msdn.microsoft.com/ja-jp/library/ms229658
(v=vs.90).aspx
の英語のコメントで
// This is a generic wndproc. It is the callback for all hooked
// windows
と書いてあったので使いましたが、正しくありませんでしょうか。
Windowsの応答に関しては制御ループ一巡の時間を測定して、
何とか使える範囲であることを確認しています。
遅いですが。
OSは書きました、ハードはPentium 4 2Gだと思います。
記事No.68841 のレス /過去ログ117より /
関連記事表示
削除チェック/
■68873
Re[6]: WndProcの処理を止める方法
□投稿者/ しま -
(2013/11/23(Sat) 10:46:38)
■
No68872
(kota さん) に返信
> ■
No68871
(しま さん) に返信
> 回答有難うございます。
>
> 言語はC#です。
> コールバックと書いたのは
> >>
http://msdn.microsoft.com/ja-jp/library/ms229658
(v=vs.90).aspx
> の英語のコメントで
> // This is a generic wndproc. It is the callback for all hooked
> // windows
> と書いてあったので使いましたが、正しくありませんでしょうか。
C# なのか C/C++ なのか文面だけではよくわからなかったからです。
決して言葉の使い方が正しいとか間違っているとかいうことではございません
> Windowsの応答に関しては制御ループ一巡の時間を測定して、
> 何とか使える範囲であることを確認しています。
> 遅いですが。
>
> OSは書きました、ハードはPentium 4 2Gだと思います。
>>開発環境、動作環境については書いてください。
言葉足らずでした。最初の投稿で書いて欲しかったという意味です
余計なことかもしれませんが、高速な動作が必要な場合はメモリーもプロセッサー(CPU)も早いほうがいいです
ソフトで解決できないことがハードウエアーを変えることで解決してしまうことがあります
記事No.68841 のレス /過去ログ117より /
関連記事表示
削除チェック/
■68877
Re[4]: WndProcの処理を止める方法
□投稿者/ Jitta -
(2013/11/23(Sat) 13:15:52)
>
■
No68865
(kota さん) に返信
> 工業用のPCにOSはXp(客指定)のOSでリアルタイムモニター
> のような使い方をしています。
どれくらいの「リアル」を求めるかにも依りますが、Windows でリアルタイムを求めるのには、無理があります。
そのことは、納得済みなのでしょうか。たとえば、I/O 要求が重なると、簡単に遅延します。
> 自作のタイマーを含めタイマーは200個ほど使っています。
> 計測器などは非同期でも構わないのですが、モーターコントロールは
> 同期が必要で、メインスレッドで処理しています。
> モーターの動きを監視し目的の場所に移動するまで、メインスレッドは
> ループで待ちます。
そもそも、モーターの制御を Windows OS でやろうというところが間違っているように思います。
いや、求める精度によるけど。
> 待っている間、測定器からのメッセージはSenndMessageで待たせます。
> ただしI/OからのStopコマンドは受け付ける為に、Doeventで処理を
> します。
この理由で、メインスレッドでなければならないとは思えません。
メインスレッドというのは、起動したときのスレッドだというだけです。
スレッドの優先度を指定しないなら、どのスレッドでも優先度は同じです。
記事No.68841 のレス /過去ログ117より /
関連記事表示
削除チェック/
■68885
Re[5]: WndProcの処理を止める方法
□投稿者/ kota -
(2013/11/23(Sat) 19:52:49)
すみません、質問の本題は、題名にあるように
WndProcを一時的に無効にする方法は有るか無いか
お聞きしたかったのです。
「無い」ということであれば、他の方法を考えます。
特にそれほど悩んでいるわけではなく、メッセージフックを
一時的に無効に出来るのであれば、そちらの方法も検討しようかな
と思った次第です。
回答者さんの回答はそんな方法はないので、Application.DoEvents()
を止めろという回答と理解しました。
納得です。
回答者さんの質問に答えているうちになぜか重い処理や、非力な
環境をどうにかしたいという方向に向かってしまいました。
多分私がいけなかったのでしょう。
申し訳ありませんでした、解決とさせていただきます。
以下質問にお答えします。
■(しま さん) に返信
>高速な動作が必要な場合はメモリーもプロセッサー(CPU)も
早いほうがいいですソフトで解決できないことがハードウエアーを
変えることで解決してしまうことがあります
全くその通りであると思います、私もXP上のプログラムなど
書きたくないのですが客指定のハードとOSです。(泣
■(よる さん) に返信
>どれくらいの「リアル」を求めるかにも依りますが、
Windows でリアルタイムを求めるのには、無理があります。
そのことは、納得済みなのでしょうか。たとえば、
I/O 要求が重なると、簡単に遅延します。
>そもそも、モーターの制御を Windows OS でやろうというところが
間違っているように思います。いや、求める精度によるけど。
I/Oはマルチスレッドタイマーでスキャンし、変化が有れば
メインスレッドにInvokeしています。
I/Oはビットイメージなので、ワード単位で8w読むだけなので、
状態が変化しても遅延はしませんが、メカニカルな押しボタンの
有効無効の判断に時間がかかります。
モーターは専用のモータードライバーが有って、PCからDLL経由で
速度、加速度、行先を指示しますが、PCの負担は大きくありません。
精度は専用ハードが0.1mm単位で制御します。
>この理由で、メインスレッドでなければならないとは思えません。
メインスレッドで同期をとるのはデバッグ環境に依存するところが
大きいのです。
VS2010によるマルチスレッドの開発環境は快適とは言えません。
私の使い方が悪いのかもしれませんが。
記事No.68841 のレス / END /過去ログ117より /
関連記事表示
削除チェック/
<<
0
>>
パスワード/
-
Child Tree
-