すいません、VB4しかやってないんです、VBAはやったけど(ぼそ) チラシの裏だって立派な書き込み空間なんだからねっ!資源の有効活用なんだからねっ!とか偉そうに言ってるけど、実は色々と書き残したいだけ

だからなに? どうしろと? くるみサイズの脳みそしかないあやしいジャンガリアンベムスターがさすらう贖罪蹂躙(ゴシックペナルティ)

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  632  : 記事  35  : コメント  11677  : トラックバック  143

ニュース


片桐 継 は
こんなやつ

かたぎり つぐ ってよむの

大阪生まれ河内育ちなんだけど
関東に住みついちゃったの
和装着付師だったりするの
エセモノカキやってたりするの
VBが得意だったりするの
SQL文が大好きだったりするの
囲碁修行中だったりするの
ボトゲ好きだったりするの
F#かわいいよF#

正体は会った人だけ知ってるの

空気読まなくてごめんなさいなの


わんくまリンク

C#, VB.NET 掲示板
C# VB.NET掲示板

わんくま同盟
わんくま同盟Blog


WindowsでGo言語
WindowsでGo言語


ネット活動


SNSは疲れました

記事カテゴリ

書庫

日記カテゴリ

ギャラリ

イベント活動

プログラムの活動

ついに開発環境がVisualStudio2010になったよ。

思えば、2005から始まって2008ときて、ここまで引きずってんのかとちょっと自分でも思ったけどw

で、ですね、色々とまたね、ちんまいことなんだけど、変わってたorz

MTA宣言しなくてもWaitAllが使えるし、プラグマもいらないし。楽になったねぇ。

ついでに、長く長く引っかかってた「EndInvokeを呼ぼうよ」問題にもやっと取りかかれた。

クルミの脳でごめんね、進化遅いんで、遅いなりにやってるもんだから、完璧なモノが欲しい人は、それなりの人の所でソースをあさったほうがいいと思うの。ほんと、ごめんね。識者からすれば「当たり前だろ」とか思う事でも、手さぐりな人間には本当に手さぐりなもんだからさ、試して動かしていくしかないんだわ。

だから、完璧であれ、と言われても無理かな。やれるだけのことはやっていくけどね。

というわけで、今のところの最新ソース。長くなったぞー(笑)

Imports System
Imports System.Threading

Module OrochSample

    Delegate Sub DrinkingSAKE()

    '酒ツボに酒を準備 
    Public inSakeTubo As New SakeTubo(2000)

    'おろちの首準備
    Public orochiHeads As New List(Of OrochiHead)

    Public Sub Main()

        Try

            '本体で首が別々に酒飲みするのを身構える   
            Dim ts As New ThreadStart(AddressOf OrochiDrinking)

            Dim workerThread As New Thread(ts)

            workerThread.Start()

            workerThread.Join()

        Catch ex As Exception

            Console.WriteLine("{0}", ex.Message)

        End Try

        Stop
    End Sub

    Private Sub OrochiDrinking()

        'まずは首を八本で飲んでみる   
        Dim headCount As Integer = 8

        '酔っ払い待ち行列を首の数だけ準備   
        Dim yoppa(headCount - 1) As WaitHandle

        orochiHeads.Capacity = headCount

        '酒飲み開始
        For i As Integer = 1 To headCount

            '飲んだ首から酔っ払いへと   
            yoppa(i - 1) = HeadDrinking(i).AsyncWaitHandle

        Next

        '全部の首が酔っ払うか切られるかするまで待機   
        WaitHandle.WaitAll(yoppa)

    End Sub

    Private Function HeadDrinking(ByVal headNo As Integer) As IAsyncResult

        '指定した番号の首に酒を飲ませる
        orochiHeads.Add(New OrochiHead(headNo))

        Dim gubi As New DrinkingSAKE(AddressOf orochiHeads(headNo - 1).Drink)

        '酒飲み開始とともに、酔っ払い待ち行列へ戻す   
        Return gubi.BeginInvoke(AddressOf HeadYoppa, gubi)

    End Function

    '酔っ払い待ち行列に何か戻ってくるたびに動く処理(CallBack)
    Private Sub HeadYoppa(ByVal asr As IAsyncResult)

        'BeginInvokeで2番目のパラメータに渡しておいたobjectを取得しなおし
        Dim yoppa As DrinkingSAKE = asr.AsyncState

        'おろちの首クラスを取得
        Dim head As OrochiHead = yoppa.Target

        'スレッドの後始末
        yoppa.EndInvoke(asr)

        'エラーがあったかどうかを確認
        If head.orochiException IsNot Nothing Then
            Console.WriteLine("スサノオさんが{0}番目の首切った!", head.Number)
        Else
            Console.WriteLine("ぷはーっ! {0}番目の首、飲み終わり!", head.Number)
        End If

    End Sub

    Public Class OrochiHead
        'おろちの首クラス

        '首が無事なのかどうか
        Public orochiException As Exception

        'お前は何番目なのかを保持
        Private meNumber As Integer
    ReadOnly Property Number As Integer
        Get
            Return meNumber
        End Get
    End Property


    '何番目の首?初期化w 
    Public Sub New(ByVal headNo As Integer)

        meNumber = headNo

    End Sub

    '酒を飲むメソッド   
    Public Sub Drink()

        Dim nowDrink As Integer
        Dim nowNokori As Integer

        Dim oneDrink As New Random
        Dim oneBreath As New Random

        Try

            '酒ツボの中の酒を飲み干す   
            While Not (inSakeTubo.Nomihoshited)

                '一回飲むたびに息継ぎ   
                Thread.Sleep(oneBreath.Next(30, 60))

                '酒つぼから飲んでみる
                If inSakeTubo.Nomihoshited Then
                    Console.WriteLine("{0}番目の首「もう酒がねぇよ!!ぷんすか」", meNumber)
                    Exit Sub
                Else
                    '一回ぐび   
                    nowDrink = oneDrink.Next(1, 100)
                    nowNokori = inSakeTubo.Nokori
                    inSakeTubo.Gubi(nowDrink)
                    If inSakeTubo.Nomihoshited Then
                        Console.WriteLine("{0}番目の首「ちきしょう!足りねぇよ!{1}のみてぇのに{2}しかねぇ!」", meNumber, nowDrink, nowNokori)
                        Exit Sub
                    Else
                        Console.WriteLine("{0}番目の首が {1} リットル ぐびっ : 残り {2} リットル", meNumber, nowDrink, inSakeTubo.Nokori)
                    End If
                End If

                'スサノオさんアップ中
                Dim cutNo As New Random
                Dim cutHead = cutNo.Next(1, 64)

                'どれかの首はねます。運が悪かったら首切りw
                If cutHead Mod meNumber = 0 Then
                    Console.WriteLine("スサノオさん「{0}番目の首はねてやんよ!」", meNumber)
                    Throw New Exception(String.Format("{0}番目の首は切られてしまった!", meNumber))
                End If

            End While

        Catch ex As Exception
            orochiException = ex
        End Try

    End Sub

    End Class

    Public Class SakeTubo
        '酒つぼクラス
        'マルチスレッドでの読み書き保護処理を集約

        Private cacheLock As New ReaderWriterLockSlim()
        Private innerSake As Integer

        '酒つぼの準備
        Public Sub New(ByVal litter As Integer)

            innerSake = litter

        End Sub

        '酒の残りはどれくらい?
        Public Function Nokori() As Integer
            cacheLock.EnterReadLock()
            Try
                Return innerSake
            Finally
                cacheLock.ExitReadLock()
            End Try
        End Function

        'ぐびぐびいくぜ!
        Public Sub Gubi(ByVal gubigubi As Integer)

            Dim retFlag As Boolean = True

            cacheLock.EnterWriteLock()
            Try
                If innerSake > gubigubi Then
                    innerSake -= gubigubi
                Else
                    innerSake = 0
                End If
            Finally
                cacheLock.ExitWriteLock()
            End Try
        End Sub

        '空っぽにしちゃうぞ!
        Public Sub Karappo()
            cacheLock.EnterWriteLock()
            Try
                innerSake = 0
            Finally
                cacheLock.ExitWriteLock()
            End Try
        End Sub

        '飲み干しちゃったかな?どーかな?
        Public Function Nomihoshited() As Boolean
            cacheLock.EnterWriteLock()
            Try
                Return (innerSake.Equals(0))
            Finally
                cacheLock.ExitWriteLock()
            End Try
        End Function

    End Class

End Module

こんな感じ。ほんまに長いw 簡単にいえば、

  1. おろちさんの首が酒を飲み始める(BeginInvoke)
  2. 8本の首がばらばらに動きはじめて、スサノオさんに首切られるor呑み終わる(スレッド処理)
  3. 呑まれる酒つぼは一つ。酒の量はスレッド間でも同じになるようにLockして処理。
  4. 戻ってきた首ごとに後始末して、よっぱらいかどうかを調べる(CallBackからEndInvoke)
  5. 全部の首がスレッド終了したら、プログラムは33行の「Stop」を処理

スレッド内でThrowされた例外を親スレッドでCatchするってのは私の脳味噌ではできないので、例外あったら保存するPublicをもっておいて、処理が終わってからここを見ることで解決することにしたん。

いちお、VisualStudio2010で動いたので、それだと大丈夫だと思う。

投稿日時 : 2010年7月31日 16:49

コメント

# re: やまたのおろちが酒をのむ・リターンズその3~片桐的マルチスレッドVBプログラミング~ 2010/07/31 23:00 通りすがり
誰も完璧なんて求めてないと思います。

http://blogs.wankuma.com/esten/archive/2008/01/23/118945.aspx
http://blogs.wankuma.com/esten/archive/2008/12/09/163043.aspx
http://blogs.wankuma.com/esten/archive/2010/03/13/187085.aspx
http://blogs.wankuma.com/esten/archive/2010/03/14/187112.aspx

こんだけ同じことを指摘されて、かつ、あなた自身がMTAにしてるのはWaitAllを使うためだ、とコメントで明記しているのですから、
あなたの脳みそがどうこうとかそんな話ではなくて、あなたは現在ではちゃんと理解している内容なのでしょう?

にも関わらず、新しい記事でもずっと間違った表現をかたくなに続けるから指摘を続けてるんですよ。

完璧など求めた記憶はありません。
間違いもしくは誤解を招く表現だという指摘を受けているだけなのに、なんで普通に受け入れられずにおかしな言い訳方向に持っていこうとするんです?


# re: やまたのおろちが酒をのむ・リターンズその3~片桐的マルチスレッドVBプログラミング~ 2010/07/31 23:57 通りすがり
>で、ですね、色々とまたね、ちんまいことなんだけど、変わってたorz
>MTA宣言しなくてもWaitAllが使えるし、プラグマもいらないし。楽になったねぇ。

変わってないのでは?
VS2010というか.NET Framework 4でもWaitAllはMTAでないと使えないようですし、
デフォルトでMTAになるから、何の指定もなくても問題なく使えるのも同じです。


# re: やまたのおろちが酒をのむ・リターンズその3~片桐的マルチスレッドVBプログラミング~ 2010/08/01 10:16 かたぎり
ということなので、通りすがりさんのおっしゃる通り、ご指摘のとおりが正しい、とのことですです。

おかしな方向になったらごめんなさいね。
指摘されて訂正したいけど、ブログの表示がおかしくなることがあるから、基本、記事はいじらないことにしたの。
検証もしなくちゃだけど、時間無いしね。

指摘してくれて、それはとてもありがたいのですよ

誤解しないでくださいね?
書かなくても動いたから、嬉しくてそう書いて、
書かないと動かない時代があったってだけだから
自分が感じた事、思った事、試した事を書いてるだけで
私は精いっぱいの記事を精いっぱいなりに書く以外にないんだもの。

とおりすがりさんもこれだけご存じなんだもの、
きっと凄いもの作るんだろうなぁ。

あとね、とおりすがりさんは指摘してブログコメントに書くけど、
それ以外に、「ブログの人に連絡」でメールできるって知ってました?
そのメールは、私にメールで送られてくる内容で、通りすがりさんには決して見えることはありません。


# re: やまたのおろちが酒をのむ・リターンズその3~片桐的マルチスレッドVBプログラミング~ 2010/08/01 18:42 通りすがり
とりあえず、以前はエラーになったという話についてですが…

想像ですが、そのときはWidowsFormアプリケーションで試したとかで、
メインスレッドがSTAに設定された状態だったんじゃないかと思いますよ。

今のコードなら、VS2005や2008でもエラーにならずに動くと思います。


Post Feedback

タイトル
名前
Url:
コメント