すらすらプログラマーへのお問い合わせ
すらすらのブログ
アクセス数  累計:000,125,036  昨日:000,000,099  本日:000,000,058
Loading
スレッド
.NET プログラミング
プロパティグリッド
印刷
リストボックス
スレッド
リストビュー
インストーラー
やってみよう!

できるVisual Studio 2015 Windows /Android/iOS アプリ対応

独習C# 第3版

VisualBasic2013パーフェクトマスター (Perfect Master SERIES)

プログラミング.NET Framework 第4版 (Microsoft Press)

VisualBasic2013逆引き大全555の極意

猫でもわかるWindowsプログラミング 第4版 (猫でもわかるプログラミング)

VisualC#2013逆引き大全555の極意

スレッドの多重起動防止 最終更新:2010/07/15
【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.