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

我知道我实际上并没有开始这个过程,因为我只是EmailSender(em, String.Empty)在 MassEmailSendingStatus 控制器的每个循环内调用工作发生的地方......我必须做些什么才能正确解决这个问题?

4

1 回答 1

0

哇,我的代码被破坏了...在获取博客代码并将其放入自己的快速项目并启动它之后,我能够看到正在发生的事情..我现在可以工作了...我将使用有点工作解决方案......现在正在努力将不仅仅是百分比返回到进度条,因此消息显示为它的工作..不知道我将如何做到这一点,但我想我会在 getCurrentProgress 方法中作为从extendedTaskRun 类返回的字符串...

于 2013-02-23T23:28:19.470 回答