Vb.net 跟踪一组任务的运行时间
我正在尝试编写一个小型VB.NET应用程序,以在工作中进行跨团队的动态时间研究。我需要的能力,有多个定时器运行单个任务,当用户完成了他们的任务,他们可以结束它,它将存储在一个CSV文件。我可以一次完成单个任务,这在业务中已经运行了一段时间。让多个任务同时运行的最佳方法是什么。我的想法是将任务添加到listview中,并将双击事件作为结束任务函数。然而,我似乎无法让计时器独立运行。有人能帮忙吗?这有意义吗 这是这个类中主要的工作量。如果这不合理,我会提前道歉。我不是程序员,这只是我在工作中练习的业余爱好 另一件事是让经过的秒数实时计算,我可以用一个标签来做,但理论上我需要一个不合适的任务量Vb.net 跟踪一组任务的运行时间,vb.net,timer,stopwatch,elapsedtime,Vb.net,Timer,Stopwatch,Elapsedtime,我正在尝试编写一个小型VB.NET应用程序,以在工作中进行跨团队的动态时间研究。我需要的能力,有多个定时器运行单个任务,当用户完成了他们的任务,他们可以结束它,它将存储在一个CSV文件。我可以一次完成单个任务,这在业务中已经运行了一段时间。让多个任务同时运行的最佳方法是什么。我的想法是将任务添加到listview中,并将双击事件作为结束任务函数。然而,我似乎无法让计时器独立运行。有人能帮忙吗?这有意义吗 这是这个类中主要的工作量。如果这不合理,我会提前道歉。我不是程序员,这只是我在工作中练习的业
Public Class runningTask
Dim timenow As DateTime = Now
Dim elapsed
Dim localTask = GlobalVars.task
Public Sub AddItem()
CreateTimer()
Dim str(3) As String
Dim itm As ListViewItem
str(0) = localTask
str(1) = timenow
str(2) = elapsed
itm = New ListViewItem(str)
frmTime.lvTimers.Items.Add(itm)
End Sub
Private Sub CreateTimer()
Dim tmr As New Timer
tmr.Interval = 1000
tmr.Enabled = True
AddHandler tmr.Tick, AddressOf GlobalTimerTick
End Sub
Private Sub GlobalTimerTick(ByVal sender As Object, ByVal e As EventArgs)
Dim t As TimeSpan = Now - timenow
elapsed = String.Format("{0:00}:{1:00}:{2:00}:{3:00}", Math.Floor(t.TotalHours), t.Minutes, t.Seconds, t.Milliseconds)
End Sub
End Class
我采用了一种更为面向对象的方法,这种方法对于计时器来说可能更经济,但是有一个非常简单的接口。核心是一个TaskItem,它跟踪作业和时间,然后是一个集合类来公开、启动和停止作业和时间。通过在尽可能低的级别上嵌入尽可能多的功能,事情会变得更简单 我只使用了一个计时器,不明白为什么一个任务需要多个计时器。如果任务项在启动时记录了
DateTime
(在我的任务项中创建时会自动记录),那么您根本不需要任何计时器。始终使用StartedTime
和DateTime.Now
(对于正在运行的任务)或CompletedTime
计算已用时间。我看不出计时器在哪里添加了什么
你将不得不为你的目的制作许多MOD。这不会保存已完成的项目,也不会将其从列表中删除,但可能会给您一个开始的位置。这也是第一件事;这里那里肯定有问题
Imports System.Collections.ObjectModel
Public Class Tasks
' slight overkill
Private Enum LVGroups
Running
Completed
End Enum
Public Enum TaskJobs
SweepFloor
BuildRobot
CleanOven
RepairRobot
EmptyTrash
TeachRobotToTalk
MakeCoffee
TeachRobotToWalk
WashDishes
TeachRobotVisualBasic
End Enum
' class for a single task
Public Class TaskItem
' these ought to be readonly; so no cheating
Public Property ID As String
Public Property EmpName As String
Public Property StartedTime As DateTime
Public Property CompletedTime As DateTime
' or job code...
Public Property Job As TaskJobs
' put in a ClassLib or Namespace
Friend Sub New(sName As String, tj As TaskJobs)
EmpName = sName
Job = tj
StartedTime = DateTime.Now
CompletedTime = DateTime.MaxValue
ID = System.Guid.NewGuid.ToString
End Sub
Public Function IsActive() As Boolean
Return (CompletedTime = DateTime.MaxValue)
End Function
Public Sub EndTask()
CompletedTime = DateTime.Now
End Sub
Public Function GetElapsed() As String
Dim t As TimeSpan
If IsActive() Then
t = DateTime.Now - StartedTime
Else
t = CompletedTime - StartedTime
End If
Return String.Format("{0:00}:{1:00}:{2:00}", Math.Floor(t.TotalHours),
t.Minutes, t.Seconds)
End Function
Public Overrides Function ToString() As String
Return String.Format("{0} {1} {2}", EmpName, Job.ToString, GetElapsed)
End Function
End Class
Private col As Collection(Of TaskItem)
Private myLV As ListView
' assign the LV when tasks are created
Public Sub New(lvTask As ListView)
myLV = lvTask
col = New Collection(Of TaskItem)
End Sub
' add new task with EmpName and JobCode
Public Sub NewTask(sName As String, tj As TaskJobs)
Dim ti As New TaskItem(sName, tj)
col.Add(ti)
' LV layout: empname, job, elapsed, ID
' but only 3 columns so that ID is "hidden"
Dim lvi As New ListViewItem(ti.EmpName)
lvi.SubItems.Add(ti.Job.ToString)
lvi.SubItems.Add(ti.GetElapsed)
lvi.SubItems.Add(ti.ID)
lvi.Group = myLV.Groups(LVGroups.Running.ToString)
myLV.Items.Add(lvi)
End Sub
' called from dbl click on a running task item
Public Sub StopTask(lvi As ListViewItem)
Dim ti As TaskItem = (From t In col Where t.ID = lvi.SubItems(3).Text).First
' the form doesnt check the status, so we must
If ti.IsActive Then
ti.EndTask()
lvi.Group = myLV.Groups(LVGroups.Completed.ToString)
End If
End Sub
' called from the form timer tick event
Public Sub UpdateDisplay()
Dim ti As TaskItem
' iterate items to get ID of runners
For Each lvi As ListViewItem In myLV.Groups(LVGroups.Running.ToString).Items
' ToDo add error checking
ti = (From t In col Where t.ID = lvi.SubItems(3).Text).First
lvi.SubItems(2).Text = ti.GetElapsed
Next
End Sub
Public Function RunnersCount() As Integer
Return GetActiveList.Count
End Function
Public Function GetCompletedList() As List(Of TaskItem)
' long form
Dim tList As New List(Of TaskItem)
For Each ti As TaskItem In col
If ti.IsActive = False Then
tList.Add(ti)
End If
Next
Return tList
' short form
'Dim list = (From t In col Where t.IsActive = False).ToList
End Function
Public Function GetActiveList() As List(Of TaskItem)
' long form
'Dim tList As New List(Of TaskItem)
'For Each ti As TaskItem In col
' If ti.IsActive Then
' tList.Add(ti)
' End If
'Next
'Return tList
' short form
Dim list = (From t In col Where t.IsActive).ToList
Return list
End Function
End Class
用法:
Public Class Form1
Private myTasks As Tasks
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
myTasks = New Tasks(Me.lvTask)
cboTask.Items.AddRange([Enum].GetNames(GetType(Tasks.TaskJobs)))
End Sub
添加任务:
myTasks.NewTask(cboEmp.Text, CType(cboTask.SelectedIndex, Tasks.TaskJobs))
停止任务:
' called from LV mousedoubleclick, so determine the item
Dim lvi As ListViewItem = lvTask.GetItemAt(e.X, e.Y)
myTasks.StopTask(lvi)
显然,停止任务可能会自动将数据附加到导出文件中。该功能将在TaskCollection类中,在该类中,它将在任务从集合中移除之前完成(可选-只要您能够区分活动和已完成的任务,它们不会影响任何事情)
计时器滴答声事件:
myTasks.UpdateDisplay()
最后,启用
选项Strict
,尤其是因为人们将根据项目的输出做出决策 谢谢,事实上我最终还是成功了。我使用的是DataGridView,并在计时器的tick事件上循环行。工作完美,我希望我记得检查答案,因为你的解决方案非常好。谢谢你的帮助!很高兴提供帮助-控制(LV vs DGV)并不重要,因为原理是一样的。当他们提供帮助时,接受/检查答案永远不会太晚。谢谢!所有项目现在正在工作,并提交到sharepoint进行报告。