ウエイト(スリープ)をする方法

解決


横浜  2010-01-22 01:06:45  No: 143090  IP: [192.*.*.*]

スリープというかウエイト処理を行いたいのですが、うまくいきません。
Sleep(500)の類はうまくいきません、例を載せてみます。



例)
作業A
System.Threading.Thread.Sleep(500)
作業B
System.Threading.Thread.Sleep(500)

が結果

System.Threading.Thread.Sleep(500)
System.Threading.Thread.Sleep(500)
作業A
作業B

となってしまいます、具体的な作業は例えばシリアルからのデーター送信などでデーター送信とデーター送信の間などに使ってみたいです。

解りやすいデストとしてはブラウザ読み込み作業などの間に設置して
テストしてみたいです(ブラウザ読み込み完了を待つは使用しないで)


どうか宜しくお願いします。

編集 削除
?  2010-01-22 09:20:46  No: 143091  IP: [192.*.*.*]

この結果というのはどういう風に確認したのですか。

編集 削除
横浜  2010-01-22 16:50:40  No: 143092  IP: [192.*.*.*]

?様ご返信ありがとうございます。

結果というのは実行してみた結果なのですが
もうすこし具体的にいうと


作業A WebBrowser1.Navigate(New Uri("http://yahoo.co.jp"))System.Threading.Thread.Sleep(2000)
作業B WebBrowser1.Navigate(New Uri("http://google.co.jp"))
System.Threading.Thread.Sleep(2000)

希望としては、Yahooを開いた後2秒後にGoogleを開きたいのですが
が結果

System.Threading.Thread.Sleep(2000)
System.Threading.Thread.Sleep(2000)
作業A
作業B
4秒固まってからGoogleを開いてしまいます。

ほんとうにこまっています、宜しくお願いします。

編集 削除
 2010-01-22 16:57:10  No: 143093  IP: [192.*.*.*]

そのコードはネットでは使えないね。
V6は知らないが、完全にバグ(不具合)そのものだ。
意味わかる?(笑)
そんなコードが有効なら、サーバーは止まりぱなしアプリも停止っぱなし、
マイクロソフト社員でも気がつくだろ(笑)
永久にハルトするようなコードが使えるわけなかろが。
どしろうと丸出しですよ。

編集 削除
YuO  2010-01-22 17:21:08  No: 143094  IP: [192.*.*.*]

Fiddlerなどのプロキシを使って,動作を見てください。
恐らく,yahoo.co.jpへの接続を行い,その後にgoogle.co.jpへの接続を行っていると思います。
なので,実際の動作としてはちゃんと行われているはずです。

ただし,見た目は別です。
Thread.Sleepでは(再)描画は一切行われません。
このため,Thread.Sleepをはさんで描かれた内容の違いで動作の有無を判定しようとしても,意味がありません。
System.Windows.Forms.Timerなどを使って,状態遷移によって「2秒後」を擬似的に作り出してください。

編集 削除
特攻隊長まるるう  2010-01-22 18:58:20  No: 143095  IP: [192.*.*.*]

> Thread.Sleepでは(再)描画は一切行われません。
[Thread.Sleep メソッド (Int32)]
http://msdn.microsoft.com/ja-jp/library/d00bd51t.aspx
>指定した時間だけ現在のスレッドを中断します。
>解説
>スレッドは、指定した時間の間は、オペレーティング システムによる実行がスケジュールされません。
書いてある通りだね。プログラムを止めてるようなイメージ。

編集 削除
横浜  2010-01-22 23:27:03  No: 143096  IP: [192.*.*.*]

なるほど、現状の解説は理解せきました、ありがとうございます。
では、私が望むような動きをさせるにはどの様にすればよいでしょうか?
大変安直な質問ですがどうすればよいか困っています。

編集 削除
将星  2010-01-22 23:56:20  No: 143097  IP: [192.*.*.*]

YuOさんが書いてくれてるじゃん。
↓じゃダメだったの?
>System.Windows.Forms.Timerなどを使って,状態遷移によって「2秒後」
>を擬似的に作り出してください。

編集 削除
横浜  2010-01-23 00:20:47  No: 143098  IP: [192.*.*.*]

すいません、
System.Windows.Forms.Timer  をググって見たのですが
使用方法を書いてるものがみつかりませんでした、あぁ、情けない・・・

そもその話しで大変申し訳ないのですが、Timerを設置するのでしょうか?
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer { Interval = 1000 }

こういうものを見つけましたがC#のようでエラーがでます。
もう少しアドバイスください、大変もうしわけないです。

編集 削除
特攻隊長まるるう  2010-01-23 03:50:43  No: 143099  IP: [192.*.*.*]

> System.Windows.Forms.Timer  をググって見たのですが
> 使用方法を書いてるものがみつかりませんでした、あぁ、情けない・・・
…ググって見たけど。
フツーに検索に引っかかるし、使用方法も書いてあるね。
世の中にこんな文字列のものなんて他に無いもん。

>こういうものを見つけましたがC#のようでエラーがでます。
C#も当然引っかかるだろうけど、C#かVB.NETくらいだから
3ページも見れば見つからないという事は有り得ないです。
というか見つかりましたし。
書いてあるけど読めないのであれば、こちらで説明しても
簡単には理解してもらえないんでしょうね。

>そもその話しで大変申し訳ないのですが、Timerを設置するのでしょうか?
Timer の使い方に何十通りも無いし、処理結果なんて時間を計る以外に無い
だろうから、何でもいいよ。
「設置する」という表現で納得するならそれでもいいし、
「デザイン画面に貼り付ける」でもいいし、「コードで追加する」
でもいいよ。ホントなんでもいい。

っつか、ググる前にヘルプ読みなよ。Sleep だって理由書いてあったでしょうに?
目は開いてる?日本語で書いてあること読めてる?
プログラムが分からないとか関係ないから。フツーに脳みそ使って
日本語が分かれば分かることを調べてよ。

編集 削除
横浜  2010-01-23 05:41:08  No: 143100  IP: [192.*.*.*]

本当にもうしわけないのですが、ソースを書いてもらうことはでできないでしょうか?初心者掲示板ということで、もうすこしお手柔らかにお願いします。

ほんとうにどうしていいかわかりません、、、

おねがいします。

環境はXP  VB2008です。

編集 削除
特攻隊長まるるう  2010-01-23 13:05:27  No: 143101  IP: [192.*.*.*]

根本的に間違ってるのが、勉強しないでプログラムしようとしてる点。
更に間違ってるのが、「初心者」だったら道行く人に「お金ください」って言って
もらえると思ってる点。

検索でちゃんとサンプルコードも分かるし、本来は自分一人で勉強して解決すべき問題。
それに対して「どうしていいか分からない」なんて発言を平気でしてしまう。結局、今まで
のレスも役立てる気は無いんですね。あまつさえ「プログラム書け」ときたもんだ。

「私は脳みそは使いません。回答者が人生を無駄に消費して作ったコードを渡しなさい」

…会う人、会う人に借金して享楽に使う人に見えるよ。
協力する気になりません。

編集 削除
たまには  2010-01-23 13:30:47  No: 143102  IP: [192.*.*.*]

特攻隊長まるるう >
たまに優しくしてあげてもいいんじゃないの
自分の子供だと思って、
首相の母親のつもりで景気よくポンとだしておあげよ

あなたの人生は他人に厳しいばかりの人生じゃないの

編集 削除
横浜  2010-01-23 14:54:33  No: 143103  IP: [192.*.*.*]

はぃ、掲示板でよくこういうパターンみたことあります、でも
ここであきらめる=勉強しない、ともなりますし・・・

ソースを書いてくれはあきらめますが
せめてヒント下さい。

そして、またお門違いといわれるかもしれませんが
【delphi】ではこのようなもので同じ動きをしますが、

  WaitTime := 2/24/60/60; //2秒待つ
  StartTime := Now;
  while True do begin
    Application.ProcessMessages;
    if StartTime + WaitTime < Now then Break;
  end;

VBでも同じような理論でしょうか?
それともまったく違う形式になるのでしょうか?

編集 削除
特攻隊長まるるう  2010-01-23 15:15:09  No: 143104  IP: [192.*.*.*]

そもそも認識が間違っているんだよ。自分の子供じゃないしw
公共の場でしょう?道端ですれ違ってるのと変わらないでしょう?
貴方は募金箱があったら必ずお金入れてるの?
ドコが厳しいのさ?貴方も普段、日常生活でやってる事では?
普通のことです。そこでナゼ無償で何かもらえると思えるのか?
別に、無償であげる人を批判はしませんよ。ナゼ無償で与える事を
強制され、しない人が厳しいと言われるのか常識を疑います。

で、ヒントというか、ほぼ答えを書いてる人もいるわけで、
話を聞かない、返事を読まない人はどうしようもないと言って
いるだけですが。

編集 削除
特攻隊長まるるう  2010-01-23 15:21:21  No: 143105  IP: [192.*.*.*]

>ほぼ答えを書いてる人
人って書くとこのスレッドでみたいに聞こえるな。
サイト。Timer のサンプルコードなんてそんなたくさん
パターン作れないでしょ?【delphi】でサンプル何個
作れる?
「VB」でサンプルコード探せばいいじゃない?
なぜ、書かせようとするのかが分からない。
ってゆーか時間の浪費。

編集 削除
魔界の仮面弁士  2010-01-23 18:04:02  No: 143106  IP: [192.*.*.*]

> 作業A WebBrowser1.Navigate(New Uri("http://yahoo.co.jp"))
> System.Threading.Thread.Sleep(2000)
> 作業B WebBrowser1.Navigate(New Uri("http://google.co.jp"))
> System.Threading.Thread.Sleep(2000)

Navigate の指示を 2 回送っても、それらが即座に処理されるわけではありません。
コントロールに対する操作は通常、End Sub や Return に到達した後で反映されます。

WebBrowser への「指示」は即座に行われていますが、メインスレッドが
作業している間や Sleep 中は、コントロールの作業も止まってしまいますので、
HTML の読み込みなども行われないというわけです。結果として、
4 秒待機したあとでブラウザが開かれたように見えるというわけです。

このような事情もあり、そもそも Sleep は作業スレッドから使う事はあっても、
画面をもつメインスレッドから呼び出すべき物ではありません。
Sleep 中は処理が完全に停止しますので、画面の再描画も行われませんし、
データを受け取ることや、マウス操作やキー入力なども
一切できなくなってしまいます。


逆に言えば、作業スレッド内からであれば Sleep を利用できます。
VB2005 以降であれば、BackgrondWorker を利用するのが楽でしょう。

'ボタンクリックでは、作業スレッドを起動するだけ
Private Sub Button1_Click( _
        ByVal sender As Object, ByVal e As EventArgs _
        ) Handles Button1.Click
    BackgroundWorker1.WorkerReportsProgress = True
    BackgroundWorker1.RunWorkerAsync()
End Sub

'下記は、作業スレッド内で行われる処理
Private Sub BackgroundWorker1_DoWork( _
        ByVal sender As Object, _
        ByVal e As System.ComponentModel.DoWorkEventArgs _
        ) Handles BackgroundWorker1.DoWork
    '作業Aをメインスレッドに依頼
    BackgroundWorker1.ReportProgress(0, "http://yahoo.co.jp")
    System.Threading.Thread.Sleep(2000) '作業スレッドを2秒間待機

    '作業Bをメインスレッドに依頼
    BackgroundWorker1.ReportProgress(0, "http://google.co.jp")
    System.Threading.Thread.Sleep(2000) '作業スレッドを2秒間待機
End Sub

'下記はメインスレッド側
Private Sub BackgroundWorker1_ProgressChanged( _
        ByVal sender As Object, _
        ByVal e As System.ComponentModel.ProgressChangedEventArgs _
        ) Handles BackgroundWorker1.ProgressChanged
    '作業スレッドから依頼された URL を表示
    WebBrowser1.Navigate(CStr(e.UserState))
End Sub

Private Sub BackgroundWorker1_RunWorkerCompleted( _
        ByVal sender As Object, _
        ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs _
        ) Handles BackgroundWorker1.RunWorkerCompleted
    MsgBox("作業が終了しました", vbInformation)
End Sub

編集 削除
答えはヘルプにあるよ  2010-01-23 18:06:24  No: 143107  IP: [192.*.*.*]

サンプルコードがヘルプにもあるよ!
Timerで検索したら一発で出ましたが?

編集 削除
いち読者  2010-01-23 21:01:20  No: 143108  IP: [192.*.*.*]

>なぜ、書かせようとするのかが分からない。
おしえてあげる気がないのなら最初からここに書き込まないで

中途半端に教えて、さらに尋ねてきたら「自分で考えな」といって
突き放す態度はいただけません
今後は発言を控えて欲しい

編集 削除
横浜  2010-01-23 21:43:48  No: 143109  IP: [192.*.*.*]

界の仮面弁士様ごていねいにありがとうございます
これを参考にがんばってみます。
>>
Navigate の指示を 2 回送っても、それらが即座に処理されるわけではありません。
コントロールに対する操作は通常、End Sub や Return に到達した後で反映されます。

は非常にためになりました、PHPなどのように上から順番に実行される
とはかぎらないのですね。



いち読者様
たしかに、何でもかんでも丸ままソースを提供するよりも
ヒントを元に自分でがんばるほうが成長するとは解っていますが
なんせ、初心者掲示板ということですのでお手柔らかにしていただければ
ありがたいです。

引き続きがんばります。

ありがとうございます。

編集 削除
しげ  2010-01-24 11:01:08  No: 143110  IP: [192.*.*.*]

すでにいろいろ回答が出ていますが、
System.Threading.Thread.Sleep
これはシステムを停止させるものです。
外部機器などからレスポンスを待ったりする時などシステムを停止させてもいい場合に使用します。
さらにこれはSystem.Threading.Thread.Sleepを開始する直前にテキストボックスに表示させる処理などがあると処理が間に合わないのか実際に表示されません。
なので、実際には作業A→500ms→作業Bなど正常に行われても実際の表示は500ms→作業A→作業Bと目に見える表示として出てしまうというものです。
500ms前に作業Aを表示したかったんだけど、急にSystem.Threading.Thread.Sleepが始まったので表示できなかった。という事。

なので、タイマーを稼動させる処理System.Windows.Forms.Timerなどで待って見れば横浜さんの目的の処理ができますよ。


>特攻隊長さん
時間の無駄では無いです。時間の無駄ならここへ書き込む事自体しませんし、教え方なども勉強になります。さらには自分は間違った記述をしているかもしれません。これを訂正させられる事も勉強になります。
ここの書き込みの仕方だって、VBの書き込み以外しない完全無視派もいれば
VBの話題すら書き込まない荒らしなんかも存在して、どのような対処がいいのかも勉強にさせてもらっています。では。

編集 削除
しげ  2010-01-24 11:22:41  No: 143111  IP: [192.*.*.*]

追加
あ、タイマーの使い方が分からなかったんですね。
他人のHPなのでリンクを貼れませんが、GoogleでVB.NETとタイマーで
検索したらゴロゴロでました。
一番手っ取り早いのがタイマーコントロールを配置する方法が手っ取り早いかと。

編集 削除
特攻隊長まるるう  2010-01-24 13:15:58  No: 143112  IP: [192.*.*.*]

>追加
>検索したらゴロゴロでました。

質問者が
>横浜 2010/01/23(土) 00:20:47 
でググってるよ。同じ条件でググったら2番目に@マークの
サンプルコード引っ掛かったよ。
WEB に公開すること前提でちゃんと記事になってるサンプル
あるのに自前のコード晒すなんて恥ずかしい事やるほど
世間知らずじゃないよ。

編集 削除
おとなげ  2010-01-24 14:29:42  No: 143113  IP: [192.*.*.*]

特攻隊長まるるう>
まあまあ

編集 削除
横浜  2010-01-24 15:26:07  No: 143114  IP: [192.*.*.*]

いまだ解決できずに、情けなく思っております。

「VB.NET  タイマー」で検索  そして  ↓
http://oshiete1.goo.ne.jp/qa1086745.html
この記事が私のしたいことと近いとおもわれるのですが、VB6で2008用に
すれば問題なく動作するのでしょうか?

また、皆様がいわれているタイマーというのは
System.Windows.Forms.Timer  のことなのでしょうか?

もちろんTimerを使用した経験はあります、たとえば現在時間の表示など
ただ、これを今回のようにウエイトに使うという方法がよくわかりません。

そもそも、ウエイト、スリープ  インターバル
どの言い方が正しいのでしょうか?

編集 削除
しげ  2010-01-24 16:19:07  No: 143115  IP: [192.*.*.*]

まず、Intervalはタイムをカウントする間隔です。
>これを今回のようにウエイトに使うという方法がよくわかりません。
Tickイベントと言うのを使うのはどうでしょう。
これはインターバル毎に実行されるイベントです。
そこにTc = Tc + 1などカウントする変数を作成しておきます。
そこにメインプログラム中に、ループで無駄な処理を回し、TC>2になったらなどの条件を付けたら待ち時間が作成されますよね?
※もちろんループの前にタイマーをスタート(Timer1.Start)をさせる必要がありますが。


>でググってるよ。同じ条件でググったら2番目に@マークの
サンプルコード引っ掛かったよ。
>使用方法を書いてるものがみつかりませんでした、あぁ、情けない・・・
この記事が私のしたいことと近いとおもわれるのですが、VB6で2008用に
すれば問題なく動作するのでしょうか? 
by横浜

まぁこうなるでしょうなぁ・・・。これが初心者です。


>自前のコード晒すなんて恥ずかしい事やるほど
世間知らずじゃないよ。
複雑なプログラムはともかく、この程度は一般勉強レベルやろ  笑
ここからアレンジしていくんだべ?

編集 削除
特攻隊長まるるう  2010-01-24 17:20:20  No: 143116  IP: [192.*.*.*]

> System.Windows.Forms.Timer  のことなのでしょうか?
System.Windows.Forms.Timer でググった話を指してるならそうなのではないの?
魔界の仮面弁士さんのは敢えて Sleep を生かす方法。
それ以外は System.Windows.Forms.Timer で。

> もちろんTimerを使用した経験はあります、たとえば現在時間の表示など
> ただ、これを今回のようにウエイトに使うという方法がよくわかりません。
この説明だけじゃ、どんなプログラム書いたか分からないので、何が分かって
何が分からないのか、こちらには伝わりませんが、

[関数]フォームロード
  [処理]タイマーの初期設定(タイマーイベントの起こる間隔設定)
[関数End]フォームロード
[関数]タイマーイベント
  [処理]現在時間の表示
[関数End]タイマーイベント

なら、

[関数]フォームロード
  [処理]タイマーの初期設定(タイマーイベントの起こる間隔設定)
[関数]フォームロードEnd
[関数]タイマーイベント
  [条件分岐]1回目の呼び出しのとき
    [処理]WebBrowser.Navigate  yahoo
    [処理]2回目呼び出しのための設定
  [条件分岐]2回目の呼び出しのとき
    [処理]WebBrowser.Navigate  goo
[関数]タイマーイベントEnd

にするだけじゃないの?


> そもそも、ウエイト、スリープ  インターバル
日本語で「一定の時間待つ」で良いんじゃないの?厳密に特定のコードと
結びついてない段階では目的が伝わればいいんだから、どれでも50歩100歩。
その際、Sleep関数が使用目的に合わないって分かっただけでは?

「一定の時間待つ」処理をウエイトする、スリープする、インターバルをとる
と表現したところで意図は伝わるけど、Sleep関数をイメージさせるスリープする
を Sleep関数が使用目的に合わないって分かった後に使用するのは状況を把握
できてない人だね。

> 複雑なプログラムはともかく、この程度は一般勉強レベルやろ  笑
> ここからアレンジしていくんだべ?
その通りだね。検索ひとつで出てくるコードだからそこを自分でコピペ
して勉強するのが一番。検索で引っ掛かったコードを掲示板に自分が作った
ようにコピペするのは著作権侵害で論外だけど、じゃあ、Tips として公開
されているレベルと同等のプログラムを掲示板に直接書込むのか?最低限の
デバッグして、コメント記入して。。。結局、どう頑張っても検索で引っ掛かる
コードとどうレベルにしかならないのに?
実に効率が悪く時間の無駄。一般勉強レベルのコードで、検索で引っ掛かった
中に自分の目的のコードがあることも分からないようなヤツは、引っ掛かった
コードを頭から全部勉強してこいや!って思います。
そんなコードをわざわざ掲示板で発表するのはボクは恥ずかしい。恥ずかしい事を
平気でするのは世間知らず。自分が世間知らずになりたく無いのでやらない事は
誰になんと言われようとやらないでしょうね。

編集 削除
横浜  2010-01-24 19:13:36  No: 143117  IP: [192.*.*.*]

解決しました。

前回もうしあげていたものを2008用に変更しているうちに
思いどおりの処理ができるようになりました。

みなさま、ほんとうに長くの間ありがとうございました。

特攻隊長まるるう様もありがとうございます、これからも
精進したします。

編集 削除