アクセス数 累計:000,125,036 昨日:000,000,099 本日:000,000,058
|
|
|
|
【Amazon ランキング:DVD - 海外映画】
|
|
前回、簡単なスレッドプログラムを作成しましたが、実はこのプログラムにはちょっとした問題があります。
前回作成したプログラムを次の手順で動かしてみてください。
1.プログラム起動
2.「スレッド開始」ボタンクリックしてスレッド開始
3.プログレスバーが動きだしてから3秒後にもう一度「スレッド開始」ボタンをクリック
上記のような操作を行うとプログレスバーの動きがおかしなったと思います。これは、はじめに起動したスレッドが終了する前に次のスレッドが起動したのでお互いにプログレスバーの値を管理しているメンバ変数
_progressValue を変更し合っているためです。
この回ではこのような現象が発生しないようにスレッドの状態をチェックしながら処理する方法を紹介します。
|
|
スレッドの状態取得 |
スレッドの多重起動を防ぐためには Thread.ThreadState プロパティの値によってそのスレッドの状態を知り適切な処理を行うことが必要です。代表的な
Thread.ThreadState プロパティの内容は次の4つです。
|
インスタンス作成時 |
:Unstarted |
|
スレッド処理中 |
:Running |
|
スレッド処理終了 |
:Stopped |
|
スレッド処理内で Sleep 中 |
:WaitSleepJoin |
上で紹介した状態の以外の状態もありますので自分でいろいろ試してみてください。
[VB]
' スレッドが停止状態でない場合は終了
If _thread.ThreadState <> ThreadState.Stopped Then
Exit Sub
End If
[C#]
// スレッドが停止状態でない場合は終了
if (_thread.ThreadState != ThreadState.Stopped)
return;
|
フォームの作成 |
|
画面は前回と同じです。
Form1 に Button, ProgressBar,Timer をはりつけます。 プロパティの内容はすべてデフォルトです。
Button:[Button1] ProgressBar:[ProgressBar1] Timer:[Timer1]
|
|
VB[Form1.vb] |
Imports System.Threading
Public Class Form1
Private _progressValue As Integer = 0
Private _thread As Thread = Nothing
Public Sub New()
' この呼び出しは、Windows フォーム デザイナで必要です。
InitializeComponent()
' プログレスバー更新タイマー開始
timer1.Interval = 200
timer1.Enabled = True
End Sub
Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles button1.Click
If Not _thread Is Nothing Then
Console.WriteLine(_thread.ThreadState.ToString())
' スレッドが停止状態でない場合は終了
If _thread.ThreadState <> ThreadState.Stopped Then
Exit Sub
End If
End If
' スレッド開始
_thread = New Thread(AddressOf ThreadProc)
_thread.Start()
End Sub
' スレッド処理
Private Sub ThreadProc()
For i As Integer = 0 To 10
'プログレスの値加算
_progressValue = i * 10
Thread.Sleep(1000)
Next
End Sub
Private Sub timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles timer1.Tick
' プログレスバー更新
Me.progressBar1.Value = _progressValue
End Sub
End Class
|
|
C#[Form1.cs] |
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace ThreadCS
{
public partial class Form1 : Form
{
private int _progressValue = 0;
private Thread _thread = null;
public Form1()
{
InitializeComponent();
// プログレス更新タイマー開始
timer1.Interval = 200;
timer1.Enabled = true;
}
private void button1_Click(object sender, EventArgs e)
{
if (_thread != null)
{
Console.WriteLine(_thread.ThreadState.ToString());
// スレッドが停止状態でない場合は終了
if (_thread.ThreadState != ThreadState.Stopped)
return;
}
// スレッド開始
_thread = new Thread(ThreadProc);
_thread.Start();
}
// スレッド処理
private void ThreadProc()
{
for (int i = 0; i <= 10; i++)
{
// プログレスの値加算
_progressValue = i * 10;
Thread.Sleep(1000);
}
}
// プログレスバーを更新するタイマー
private void timer1_Tick(object sender, EventArgs e)
{
// プログレスバー更新
this.progressBar1.Value = _progressValue;
}
}
}
|
|
|
※このページで紹介しているサンプルコードについて管理者は動作保障をいたしません※
※サンプルコードを使用する場合は、自己責任でお願いします※
|
【楽天 ランキング:スマートフォン】
|
|
|
|
このサイトはフリーソフトのMerge HTMLで作成されています。
このサイトはリンクフリーです。
|
ページの先頭に戻る |
Copyright© 2010-2015 Jun.Shiozaki All rights reserved. |
|
|
|