0

これはvb.net mvc 3アプリケーションです..私は非同期とスレッドの組み合わせが初めてなので、これは2つのレベルで頭を悩ませています.違反を使用してください。このタスクだけでなく、他のオプションについても、Java を介して更新されるプログレス バーを追加したいと思います。プログレスバーが表示されない問題のようです...

以下は私のextendedTaskRunクラスです:

   Imports System.Collections.Generic
   Imports System.Linq
   Imports System.Threading
   Namespace ExtendedTaskHandler

''' <summary>
''' Long Running Test Class.
''' </summary>
Public Class extendedTaskRun

    Private Shared syncRoot As New Object()

    ''' <summary>
    ''' Gets or sets the process status.
    ''' </summary>
    ''' <value>The process status.</value>
    Private Shared Property ProcessStatus() As IDictionary(Of String, Integer)
        Get
            Return m_ProcessStatus
        End Get
        Set(value As IDictionary(Of String, Integer))
            m_ProcessStatus = value
        End Set
    End Property
    Private Shared m_ProcessStatus As IDictionary(Of String, Integer)

    ''' <summary>
    ''' Initializes a new instance of the <see cref="extendedTaskRun"/> class.
    ''' </summary>
    Public Sub New()
        If ProcessStatus Is Nothing Then
            ProcessStatus = New Dictionary(Of String, Integer)()
        End If
    End Sub

    Public Sub SetStatus(ByVal id As String, ByVal value As Integer)
        SyncLock syncRoot
            ProcessStatus(id) = value
        End SyncLock
    End Sub

    ''' <summary>
    ''' Processes the long running action.
    ''' </summary>
    ''' <param name="id">The id.</param>
    Public Function ProcessLongRunningAction(id As String) As String
        For i As Integer = 1 To 100
            Thread.Sleep(100)
            SyncLock syncRoot
                ProcessStatus(id) = i
            End SyncLock
        Next
        Return id
    End Function

    ''' <summary>
    ''' Adds the specified id.
    ''' </summary>
    ''' <param name="id">The id.</param>
    Public Sub Add(id As String)
        SyncLock syncRoot
            ProcessStatus.Add(id, 0)
        End SyncLock
    End Sub

    ''' <summary>
    ''' Removes the specified id.
    ''' </summary>
    ''' <param name="id">The id.</param>
    Public Sub Remove(id As String)
        SyncLock syncRoot
            ProcessStatus.Remove(id)
        End SyncLock
    End Sub

    ''' <summary>
    ''' Gets the status.
    ''' </summary>
    ''' <param name="id">The id.</param>
    Public Function GetStatus(id As String) As Integer
        SyncLock syncRoot
            If ProcessStatus.Keys.Where(Function(x) x = id).Count = 1 Then
                Return ProcessStatus(id)
            Else
                Return 100
            End If
        End SyncLock
    End Function
End Class
End Namespace

次に、私のコントローラーは次のとおりです。

        Public Function MassEmailStatus() As ActionResult
        MassEmailAddressList = TempData("emailaddresses")
        TempData.Clear()
        TempData.Add("emailaddresses", MassEmailAddressList)
        Return View()
    End Function

    Public Function MassEmailSendingStatus(ByVal id As String) As ActionResult
        Dim d As List(Of String) = TempData("emList")
        Dim EmailCount As Integer = d.Count
        Dim triedCount As Integer = 0

        Dim extendedTaskRun As New extendedTaskRun
        extendedTaskRun.Add(id)
        Dim percentDone As Integer = 0
        While Not (triedCount = EmailCount)
            For Each em In d
                EmailSender(em, String.Empty)
                triedCount += 1
                percentDone = EmailCount / 100 + triedCount
                extendedTaskRun.SetStatus(id, percentDone)
            Next
        End While
        extendedTaskRun.Remove(id)
        Return View()
    End Function

次に、MassEmailStatus ビューは次のようになります。

  @Code 
ViewData("Title") = "MassEmailSendingStatus"
TempData.Add("emList", TempData("emailaddresses"))
end Code

 <div>
 <a href="#" id="startProcess">Start Long Running Process</a>
 </div>
 <br />
<div id="statusBorder">
<div id="statusFill">
</div>
 </div>
 <script type="text/javascript">
  var uniqueId = '@Guid.NewGuid().ToString()';
  var tdata = '@TempData("emailaddresses")';
          $(document).ready(function (event) {
          $('#startProcess').click(function () {
              $.post("MassEmailSendingStatus", { id: uniqueId }, function () {
              $('#statusBorder').show();
              getStatus();
          });
          event.preventDefault;
      });
  });

  function getStatus() {
      var url = 'Admin/GetCurrentProgress/' + uniqueId;
      $.get(url, function (data) {
          if (data != "100") {
              $('#status').html(data);
              $('#statusFill').width(data);
              window.setTimeout("getStatus()", 100);
          }
          else {
              $('#status').html("Done");
              $('#statusBorder').hide();
              alert("The Long process has finished");
          };
      });
  }

</script>

これらはブログで言及された追加機能であり、私のコードに含まれていますが、コードを見ると正しく接続できないことがわかります。

    Private Delegate Function ProcessTask(id As String) As String
    Private extendedRunClass As New extendedTaskRun

    ''' <summary>
    ''' Starts the long running process.
    ''' </summary>
    ''' <param name="id">The id.</param>
    Public Sub StartLongRunningProcess(id As String)
        extendedRunClass.Add(id)
        Dim processTask As New ProcessTask(AddressOf extendedRunClass.ProcessLongRunningAction)
        processTask.BeginInvoke(id, New AsyncCallback(AddressOf EndLongRunningProcess), processTask)
    End Sub

    ''' <summary>
    ''' Ends the long running process.
    ''' </summary>
    ''' <param name="result">The result.</param>
    Public Sub EndLongRunningProcess(result As IAsyncResult)
        Dim processTask As ProcessTask = DirectCast(result.AsyncState, ProcessTask)
        Dim id As String = processTask.EndInvoke(result)
        extendedRunClass.Remove(id)
    End Sub

    ''' <summary>
    ''' Gets the current progress.
    ''' </summary>
    ''' <param name="id">The id.</param>
    Public Function GetCurrentProgress(id As String) As ContentResult
        Me.ControllerContext.HttpContext.Response.AddHeader("cache-control", "no-cache")
        Dim currentProgress = extendedRunClass.GetStatus(id).ToString()
        Return Content(currentProgress)
    End Function

MassEmailSendingStatus コントローラーの for each ループ内で、作業が発生する場所を呼び出すだけで、実際にプロセスを開始していないことを知っていEmailSender(em, String.Empty)ます...これを正しく修正するにはどうすればよいですか?

4

1 に答える 1

0

うわー、私のコードは強打されました...ブログコードを取得し、それを独自の簡単なプロジェクトに投入して開始した後、何が起こっているのかを見ることができました..今は動作しています...これを更新します少し作業中のソリューション...プログレスバーにパーセンテージ以上を返す作業を行っているため、メッセージが作業中として表示されます..どうやってそれを行うのかわかりませんが、getCurrentProgressメソッド内でextendedTaskRun クラスからの文字列の戻り値...

于 2013-02-23T23:28:19.470 に答える