2013-02-23 158 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類返回的字符串...