这是一个 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 控制器的每个循环内调用工作发生的地方......我必须做些什么才能正确解决这个问题?