C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[29]: スレッドプール処理のキャンセルについて [2]


(過去ログ 54 を表示中)

[トピック内 45 記事 (41 - 45 表示)]  << 0 | 1 | 2 >>

■30643 / inTopicNo.41)  Re[26]: スレッドプール処理のキャンセルについて
  
□投稿者/ 片桐 (121回)-(2008/12/29(Mon) 11:19:07)
一番大事な変数が放置のような……

Print.batchCancelFlg のアドレスがスレッド間で保護されてませんですよ。

書き込むときと読み出すときに、InterlockedなりSyncLockなり必要ではないかなぁと。
あちこちでアクセスしてますし。

あと、ソースよんで思ったのですけれど、Print.Runでスレッドプールに入って待つのは1スレッド?
すると、実は呼び出し元スレッド待ち側で待ち処理をするまでの間にスレッドプールの
スレッドがすでに処理終わってて、インスタンスいらないよーって使用済になってない?

あ、それに、Print.RunがBeginInvokeじゃないから、処理終わるまでクリックイベントが終わらない気もする。
で、Print処理するオブジェクトSharedじゃないから、せっかくSharedにしたStartとEndの変数は
常にStartもEndも1になりそうな……ってことは、Start<>End のIF文がFALSEとなる可能性も低いような……
実際のスレッドプールに入れてる処理が長くで大きいなら有り得るけれど……

っとソースをみて、感想をつらつらと。

引用返信 編集キー/
■30650 / inTopicNo.42)  Re[27]: スレッドプール処理のキャンセルについて
□投稿者/ なちゃ (243回)-(2008/12/29(Mon) 18:41:46)
本当に必須なのはEndだけっぽいですが、まあ全部同期しといた方が明確でいいでしょう。
パブリックな変数ではなくて、全部同期とったプロパティにするといいです。

ロックする変数というかオブジェクトは静的にする必要があります。
Meだと意味がありません。
そういう意味で今のEndは正しく同期出来ていません。
ただ、うまくいってない原因とはおそらく違うでしょう。
ここの同期の問題はそうそう表に出ることはありません。

印刷データ作成に時間がかかるなら、作成途中でも随時チェックがないと、キャンセルに長い時間がかかる恐れがあります。
ただこれも、今までのやりとりからうまくいってない原因とは違うようですが。

引用返信 編集キー/
■30651 / inTopicNo.43)  Re[27]: スレッドプール処理のキャンセルについて
□投稿者/ なちゃ (244回)-(2008/12/29(Mon) 18:50:38)
No30643 (片桐 さん) に返信
> Print.batchCancelFlg のアドレスがスレッド間で保護されてませんですよ。
アドレスを保護するってあまり言わない気が…言いたい意味はなんとなく分からんでもないですが…

> あと、ソースよんで思ったのですけれど、Print.Runでスレッドプールに入って待つのは1スレッド?
> すると、実は呼び出し元スレッド待ち側で待ち処理をするまでの間にスレッドプールの
> スレッドがすでに処理終わってて、インスタンスいらないよーって使用済になってない?

ちょっと意味がよく分かりません。
終わってるならそれでいいような…
まあ何のためにインスタンスにしてるとか、別の意味で微妙なとこはあります。
もしロックでMeを使うためなら、前にも書きましたがこれではうまくいきません。

> あ、それに、Print.RunがBeginInvokeじゃないから、処理終わるまでクリックイベントが終わらない気もする。
どういうことでしょう?
引用返信 編集キー/
■30731 / inTopicNo.44)  Re[28]: スレッドプール処理のキャンセルについて
□投稿者/ らんぺるーる (58回)-(2009/01/05(Mon) 14:28:36)
スレッドから参照する変数の扱いについてですが、
皆様のご指摘を反映して以下のようにしました。
問題ないでしょうか。
アクセスする場合は必ずプロパティを使用することにし、
プロパティ内でロックしました。

*本修正をいれても、なちゃさんの予想通り、今回の件は解消されていません。
 (メイン処理でSleepしても、スレッド処理が実行されていないようです。)

  '変数を全てプライベートに変更する。
Private Shared _LockObject As New Object
Private Shared poolCount_start As Integer = 0 '以前のソースのstartです。
Private Shared poolCount_end As Integer = 0  '以前のソースのendです。
Private Shared batchCancelFlg As Boolean = False

  '上記のメンバにアクセスする場合は、必ず以下のプロパティでアクセスする。
Public Shared Property ProBatchCancelFlg As Boolean
Get
SyncLock _LockObject
Return batchCancelFlg
End SyncLock
End Get
Set(ByVal value As Boolean)
SyncLock _LockObject
batchCancelFlg = value
End SyncLock
End Set
End Property

Public Shared Property ProPoolCount_start As Integer
Get
SyncLock _LockObject
Return poolCount_start
End SyncLock
End Get
Set(ByVal value As Integer)
SyncLock _LockObject
poolCount_start = poolCount_start + value
End SyncLock
End Set
End Property

Public Shared Property ProPoolCount_end As Integer
Get
SyncLock _LockObject
Return poolCount_end
End SyncLock
End Get
Set(ByVal value As Integer)
SyncLock _LockObject
poolCount_end = poolCount_end + value
End SyncLock
End Set
End Property

>片桐さん

BeginInvokeについてはあまり詳しくはないのですが、
クリックイベントはスレッド処理の完了に関わらず完了しています。
(完了していないと、呼び出し元のフォームに操作が戻りませんよね?)

また、今回のスレッドの最大数は10件と設定しています。
System.Threading.ThreadPool.SetMaxThreads(10,10)

10件以内であれば、スレッド処理は平行して実行されています。
10件以上印刷処理を繰り返した場合は、プールにたまっています。
(12件同時に印刷要求を出した場合は、2件がプールにたまります。)

startは、スレッドプールに登録する時に加算し、
endは、スレッド処理終了時に加算するので、
startとendは常に同じにはなりません。
(ここのカウントはデバックモードで確認していますが、
うまくいっているようです。)
引用返信 編集キー/
■30733 / inTopicNo.45)  Re[29]: スレッドプール処理のキャンセルについて
□投稿者/ らんぺるーる (59回)-(2009/01/05(Mon) 14:38:02)
すみません、通常モードになっておりました。図表モードで再投稿いたします。
使用方法を補足で記載します。

Setプロパティを使用するときは、必ず1を加算します。
'プール総数に1加算する。
ProPoolCount_start = 1

Getするときはそのまま使用します。
'スレッド処理が全て完了していない場合
If ProPoolCount_start <> ProPoolCount_end Then
    XXX
End If

    Private Shared _LockObject As New Object
    Private Shared poolCount_start As Integer = 0
    Private Shared poolCount_end As Integer = 0
    Private Shared batchCancelFlg As Boolean = False

    Public Shared Property ProBatchCancelFlg As Boolean
        Get
            SyncLock _LockObject
                Return batchCancelFlg
            End SyncLock            
        End Get
        Set(ByVal value As Boolean)
            SyncLock _LockObject
                batchCancelFlg = value
            End SyncLock 
        End Set
    End Property

    Public Shared Property ProPoolCount_start As Integer
        Get
            SyncLock _LockObject
                Return poolCount_start
            End SyncLock            
        End Get
        Set(ByVal value As Integer)
            SyncLock _LockObject
                poolCount_start = poolCount_start + value
            End SyncLock 
        End Set
    End Property

    Public Shared Property ProPoolCount_end As Integer
        Get
            SyncLock _LockObject
                Return poolCount_end
            End SyncLock            
        End Get
        Set(ByVal value As Integer)
            SyncLock _LockObject
                poolCount_end = poolCount_end + value
            End SyncLock 
        End Set
    End Property

引用返信 編集キー/

<前の20件
トピック内ページ移動 / << 0 | 1 | 2 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -