2013-02-23 131 views
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控制器的每个循环......我必须做什么才能正确解决这一问题?

回答

0

WOW my code was whacked ...将博客代码拿到自己的快速项目中并启动后,我能够看到发生了什么......我现在正在工作......我会使用工作解决方案稍微更新一下...现在正在将不止百分比的数据返回到进度条,所以消息显示为工作状态。不知道如何做到这一点,但即时通讯思考我会在getCurrentProgress方法作为从extendedTaskRun类返回的字符串...