0

私のテストの有効性について、セカンドオピニオンを求めています。

簡単に言うと、MMF を使用して、WinForms クライアントから Windows サービスへの同期メソッド呼び出しをシミュレートしています。here で説明されている理由により、WCF も名前付きパイプもこれには適していません。

私のプロトタイプでは、2 つの単純なアプリケーションを作成しました。コンソール アプリは WinForms の「クライアント」を表し、WinForms アプリは WinService の「サーバー」を表します。

2 つの主な問題を克服する必要がありました。1) サーバーのタイマーが 3 秒に 1 回しか起動しない、2) OS がミューテックスを取得して解放するのに少なくとも 1 秒かかるようです。この 2 番目の点が気になります。プロセスは瞬時に行われると思っていたのですが、どうやら私は間違っているようです。

これら 2 つの問題に対処するために、私は Thread.Sleep を使用しました。サーバーのタイマーを 2 秒間待機し、mutex 処理を 1 秒間待機します。これらの間隔より短い間隔では、断続的な読み取り/書き込み同期エラーが発生します。もちろん、コードを自由に微調整して、独自の結果を取得してください。

私のテストは、サーバーで「メソッド」を「呼び出し」、応答をログ ファイルに書き込む、クライアントでの 30,000 回の反復ループで構成されています。現在、エラーなしで 22,500 回まで繰り返しています。

私の質問: 私のテストに問題がある人はいますか? MSDN の投稿 (上記のリンク) に示されている要件を考えると、これまでの結果は安定した設計を示していますか?

とはいえ、私のアーキテクチャを改善できるのであれば、それについて非常に興味があります。

コードは次のとおりです。

コンソール (クライアント)

Imports System.IO
Imports System.IO.MemoryMappedFiles
Imports System.Threading
Imports System.Text
Imports System.Security.Cryptography

Module Main
  Sub Main()
    Dim _
      sForward,
      sReverse,
      sOutput As String

    Console.WriteLine("Enter a string to reverse:")

    For iCount As Integer = 0 To 29999
      sForward = GetRandomString(7)
      sReverse = ReverseString(sForward)
      sOutput = sForward & " => " & sReverse

      File.AppendAllText("Output.log", sOutput & vbCrLf)

      Console.WriteLine(sOutput)
      Thread.Sleep(1000)
    Next

    Console.ReadLine()
  End Sub

  Private Function GetRandomString(Length As Integer) As String
    Dim sSeedText As String
    Dim oBuilder As StringBuilder
    Dim aBuffer As Byte()
    Dim oCrypto As RNGCryptoServiceProvider

    sSeedText = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    oBuilder = New StringBuilder
    aBuffer = New Byte(Length - 1) {}
    oCrypto = New RNGCryptoServiceProvider

    oCrypto.GetNonZeroBytes(aBuffer)

    For Each bByte As Byte In aBuffer
      oBuilder.Append(sSeedText.Chars(bByte Mod sSeedText.Length))
    Next

    Return oBuilder.ToString
  End Function

  Private Function ReverseString(Data As String) As String
    Dim lIsOwner As Boolean
    Dim iLength As Integer
    Dim aData As Byte()

    aData = Encoding.Unicode.GetBytes(Data)
    iLength = aData.Length

    Using oFile As MemoryMappedFile = MemoryMappedFile.CreateNew("{99EC7026-0059-4D48-99B1-B400BDACBDD8}", 1024)
      Using oMutex As New Mutex(True, "{35C4F5C6-874B-4536-901A-D5382B7E2B9C}", lIsOwner)
        '*=====================================================================
        '  Wait for the server's Timer.Tick event to fire
        '*=====================================================================
        Thread.Sleep(2000)
        '*=====================================================================

        Using oStream As MemoryMappedViewStream = oFile.CreateViewStream(0, 0)
          Using oWriter As New BinaryWriter(oStream)
            oWriter.Write(iLength)
            oWriter.Write(aData)
          End Using
        End Using

        oMutex.ReleaseMutex()

        '*=====================================================================
        '  Wait for the server to acquire and then release the mutex
        '*=====================================================================
        Thread.Sleep(1000)
        '*=====================================================================

        oMutex.WaitOne()

        Using oStream As MemoryMappedViewStream = oFile.CreateViewStream(iLength + 4, 0)
          Using oReader As New BinaryReader(oStream)
            With oReader
              aData = .ReadBytes(.ReadInt32)
            End With
          End Using
        End Using

        oMutex.ReleaseMutex()
      End Using
    End Using

    Return Encoding.Unicode.GetString(aData)
  End Function
End Module

WinForms (サーバー)

'*=============================================================================
'
'   Add a ListBox
'   Add a Background Worker
'   Add a Windows Forms Timer
'     Interval = 3000
'     Enabled = True
'
'*=============================================================================

Imports System.IO
Imports System.IO.MemoryMappedFiles
Imports System.ComponentModel
Imports System.Threading
Imports System.Text

Public Class Main
  Private Sub tmrTimer_Tick(Sender As Object, e As EventArgs) Handles tmrTimer.Tick
    Dim lIsOpen As Boolean
    Dim oFile As MemoryMappedFile

    tmrTimer.Stop()

    Try
      lIsOpen = True
      oFile = MemoryMappedFile.OpenExisting("{99EC7026-0059-4D48-99B1-B400BDACBDD8}")
      bgwWorker.RunWorkerAsync(oFile)

    Catch ex As FileNotFoundException
      lIsOpen = False

    End Try

    If Not lIsOpen Then
      tmrTimer.Start()
    End If
  End Sub

  Private Sub bgwWorker_DoWork(Sender As Object, e As DoWorkEventArgs) Handles bgwWorker.DoWork
    Dim iLength As Integer
    Dim sData As String
    Dim aData As Byte()

    Using oFile As MemoryMappedFile = e.Argument
      Using oMutex As Mutex = Mutex.OpenExisting("{35C4F5C6-874B-4536-901A-D5382B7E2B9C}")
        oMutex.WaitOne()

        Using oStream As MemoryMappedViewStream = oFile.CreateViewStream(0, 0)
          Using oReader As New BinaryReader(oStream)
            With oReader
              aData = .ReadBytes(.ReadInt32)
            End With
          End Using
        End Using

        sData = Encoding.Unicode.GetString(aData)
        aData = Encoding.Unicode.GetBytes(New String(sData.Reverse.ToArray))
        iLength = aData.Length

        Using oStream As MemoryMappedViewStream = oFile.CreateViewStream(iLength + 4, 0)
          Using oWriter As New BinaryWriter(oStream)
            oWriter.Write(iLength)
            oWriter.Write(aData)
          End Using
        End Using

        oMutex.ReleaseMutex()
      End Using
    End Using

    e.Result = sData
  End Sub

  Private Sub bgwWorker_RunWorkerCompleted(Sender As Object, e As RunWorkerCompletedEventArgs) Handles bgwWorker.RunWorkerCompleted
    lstArguments.Items.Add(e.Result)
    tmrTimer.Start()
  End Sub
End Class
4

0 に答える 0