tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルSystem.Threading.Timeクラス?
記事No8528
投稿日: 2009/01/06(Tue) 18:36
投稿者ひでと
お世話になります。
Timerコンポーネントを使って、ボタンを押すとタイマーが動く処理を行っていましたが、
時間の誤差が大きくて困っています。
http://www.atmarkit.co.jp/fdotnet/dotnettips/373threadtimer/threadtimer.html
にSystem.Threading.Timeクラスを使用する方法が書いてあるのですが、
内容的に理解できず、またどのように試してよいのかわかりません。
下のような処理をSystem.Threading.Timeクラスで行うにはどのようにすれば
良いのでしょうか?


Public Class Test
    Dim Len As Long

    Private Sub bStart_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles bStart.Click
        Me.Timer1.Start()
        Len = 0
    End Sub

    Private Sub bStop_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles bStop.Click
        Me.Timer1.Stop()
        Debug.Print(Len)
    End Sub

    Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Len = Len + 1
    End Sub
End Class

[ツリー表示へ]
タイトルRe: System.Threading.Timeクラス?
記事No8535
投稿日: 2009/01/07(Wed) 11:55
投稿者花ちゃん
私だけかも知れませんが、何の為に、何をどのようにしたいのかが、
今一理解できませんので、何をどのように答えたらいいのかが解りません。
(投稿されたコードでは推測もできません)

 http://hanatyan.sakura.ne.jp/hazimeni.htm#keijiban

>内容的に理解できず、またどのように試してよいのかわかりません。

指定時間毎(1秒)にイベントを発生させたいならリンク先にサンプルがあったかと。

Public Class Form1

Private aTimer As New System.Timers.Timer()
Private Count As Integer

Private Sub Button1_Click(ByVal sender As System.Object, _
                          ByVal e As System.EventArgs) Handles Button1.Click
   AddHandler aTimer.Elapsed, AddressOf OnTimedEvent
   aTimer.Interval = 1000
   aTimer.Enabled = True
End Sub

Private Sub OnTimedEvent(ByVal source As Object, _
                         ByVal e As System.Timers.ElapsedEventArgs)
   Count += 1
   Debug.Print(Count.ToString)
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, _
                          ByVal e As System.EventArgs) Handles Button2.Click
   aTimer.Enabled = False
   GC.KeepAlive(aTimer)
End Sub

Private Sub Form1_FormClosed(ByVal sender As Object, _
                  ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
   aTimer.Enabled = False
   GC.KeepAlive(aTimer)
End Sub

End Class

[ツリー表示へ]
タイトルRe^2: System.Threading.Timeクラス?
記事No8536
投稿日: 2009/01/07(Wed) 16:52
投稿者ひでと
> 私だけかも知れませんが、何の為に、何をどのようにしたいのかが、
> 今一理解できませんので、何をどのように答えたらいいのかが解りません。
> (投稿されたコードでは推測もできません)
申し訳ありません。

>
> 指定時間毎(1秒)にイベントを発生させたいならリンク先にサンプルがあったかと。
サンプルであったのが以下のようでした

' threadtimer.vb

Imports System
Imports System.Threading

Public Class ThreadTimerTest
  Shared Sub Main()
    Dim ttt As ThreadTimerTest = New ThreadTimerTest()
    ttt.Run()
  End Sub

  Public Sub Run()
    Dim timerDelegate As TimerCallback _
      = New TimerCallback(AddressOf MyClock)
    Dim timer As Timer _
      = New Timer(timerDelegate, Nothing, 0, 1000)

    Console.ReadLine() ' キーが押されるまで待機
  End Sub

  Public Sub MyClock(o As Object)
    Console.WriteLine(DateTime.Now)
    ' 出力例:
    ' 2005/11/08 19:59:10
    ' 2005/11/08 19:59:11
    ' 2005/11/08 19:59:12
    ' ……
  End Sub
End Class

' コンパイル方法:vbc threadtimer.vb
というものでしたが、Formとどのように関連づけていいのかが、良く分かりませんでした。



>
> Public Class Form1
>
> Private aTimer As New System.Timers.Timer()
> Private Count As Integer
>
> Private Sub Button1_Click(ByVal sender As System.Object, _
>                           ByVal e As System.EventArgs) Handles Button1.Click
>    AddHandler aTimer.Elapsed, AddressOf OnTimedEvent
>    aTimer.Interval = 1000
>    aTimer.Enabled = True
> End Sub
>
> Private Sub OnTimedEvent(ByVal source As Object, _
>                          ByVal e As System.Timers.ElapsedEventArgs)
>    Count += 1
>    Debug.Print(Count.ToString)
> End Sub
>
> Private Sub Button2_Click(ByVal sender As System.Object, _
>                           ByVal e As System.EventArgs) Handles Button2.Click
>    aTimer.Enabled = False
>    GC.KeepAlive(aTimer)
> End Sub
>
> Private Sub Form1_FormClosed(ByVal sender As Object, _
>                   ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
>    aTimer.Enabled = False
>    GC.KeepAlive(aTimer)
> End Sub
>
> End Class

いただいた処理でいまひとつ理解できない部分がありますので、もう少しお願いいたします。

1.System.Timers.Timer()とSystem.Threading.Timerは同じものでしょうか?
2.GC.KeepAlive の説明で
「指定したオブジェクトを参照し、現在のルーチンの開始時からこのメソッドが呼び出される時点までの間、そのオブジェクトをガベージ コレクションの対象から外します。」
とありまして、この意味がもう1つなのですが、
この処理の場合「タイマーを止める」って単純に考えてよいのでしょうか?

[ツリー表示へ]
タイトルRe^3: System.Threading.Timeクラス?
記事No8537
投稿日: 2009/01/07(Wed) 18:23
投稿者花ちゃん
> 1.System.Timers.Timer()とSystem.Threading.Timerは同じものでしょうか?

失礼しました、いつの間にか違うリンク先を参照していました。

Public Class Form1

Private count As Integer = 0
Private timer As System.Threading.Timer

Private Sub Button1_Click(ByVal sender As System.Object, _
                          ByVal e As System.EventArgs) Handles Button1.Click
   Dim timerDelegate As Threading.TimerCallback = New Threading.TimerCallback(AddressOf MyClock)
   timer = New Threading.Timer(timerDelegate, Nothing, 0, 1000)
End Sub

Public Sub MyClock(ByVal o As Object)
   count += 1
   Debug.WriteLine(count.ToString)
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, _
                          ByVal e As System.EventArgs) Handles Button2.Click
   timer.Dispose()
End Sub

End Class

>2.GC.KeepAlive の説明で
詳しくは、私も知りませんが、MSDN のサンプルで使用されていたので付加しました。
使用したメモリの解放処理に関する処理だと思います。無くても問題ないかも?。

[ツリー表示へ]
タイトルRe^4: System.Threading.Timeクラス?
記事No8538
投稿日: 2009/01/07(Wed) 18:42
投稿者ひでと
ありがとうございました。
いただいた処理を勉強させていただきます。

[ツリー表示へ]
タイトルRe^3: System.Threading.Timeクラス?
記事No8539
投稿日: 2009/01/07(Wed) 19:25
投稿者魔界の仮面弁士
> 1.System.Timers.Timer()とSystem.Threading.Timerは同じものでしょうか?
3 つのタイマの違いについては、下記を参照してください。

http://www.atmarkit.co.jp/fdotnet/dotnettips/373threadtimer/threadtimer.html
http://www.atmarkit.co.jp/fdotnet/dotnettips/374timerstimer/timerstimer.html
http://www.atmarkit.co.jp/fdotnet/dotnettips/372formstimer/formstimer.html

通常の用途であれば、Windows アプリでは System.Windwos.Forms を使うのが一般的です。
これはメッセージベースのタイマーであるため、手軽に扱えますが、その反面、
何か重い処理が行われている場合、イベントの発生を取りこぼす可能性があります。

他の 2 つのタイマーは別スレッドで動作するため、そうした問題はありませんが、
マルチスレッドを意識したコーディングが必要となるので、扱いには注意が必要です。


> 2.GC.KeepAlive の説明で
花ちゃんさんのコードの意図は分かりませんが、GC.KeepAlive メソッドそのものは、
スコープの短いオブジェクト(ローカル変数)に対し、未使用と誤解されたオブジェクトが、
ガベージコレクトの対象とみなされないよう、有効期間を延長させるために使われます。
http://blogs.wankuma.com/shuujin/archive/2007/05/15/76794.aspx
http://www.ailight.jp/blog/kazuk/archive/2005/03/22/5217.aspx

# という事で、メソッド内で回収されるタイミングを遅らせるためのものといった
# 認識でいるのだけれども……間違ってたら誰かフォローよろしく。

[ツリー表示へ]
タイトルRe^4: System.Threading.Timeクラス?
記事No8540
投稿日: 2009/01/07(Wed) 19:51
投稿者花ちゃん
> 花ちゃんさんのコードの意図は分かりませんが、GC.KeepAlive メソッドそのものは、
> スコープの短いオブジェクト(ローカル変数)に対し、未使用と誤解されたオブジェクトが、
> ガベージコレクトの対象とみなされないよう、有効期間を延長させるために使われます。

すみません、私が間違っていたようです。ローカル変数 に対して使用されていたのを
そのまま必要かな?と思って使ってました。
MSDN の下記の解説がよく理解できなかったので。

Timer を使用している間は、このクラスへの参照を保持しておく必要があります。
他のマネージ オブジェクトと同様、まったく参照されていない場合、Timer は
ガベージ コレクションの対象となります。
Timer がアクティブであっても、ガベージ コレクションの対象から除外されることは
ありません。

[ツリー表示へ]