我在mvc中有两个动作,在一个中我开始一个全局秒表而在另一个中我停止了它,但无论经过多长时间,经过的时间总是为0。这两个事件都是由按钮点击触发的。我的怀疑是按钮的帖子弄乱了我的时间过去了吗?如果是这样的话有什么办法吗?
public Stopwatch stopwatch = new Stopwatch();
public ActionResult Start()
{
stopwatch.Start();
return RedirectToAction("Index");
}
public ActionResult Stop(int workid)
{
stopwatch.Stop();
TimeSpan ts = stopwatch.Elapsed;
int hours = ts.Hours;
int mins = ts.Minutes;
using (ZDevContext db = new ZDevContext())
{
DashboardHelper dashhelper = new DashboardHelper(db);
dashhelper.RecordTimeSpent(workid, hours, mins);
}
return View("Index");
}
答案 0 :(得分:5)
它与StopWatch不同 - 为每个请求重新创建控制器。你需要在某个地方坚持秒表。
您可以将开始时间保留在static Dictionary<int,DateTimeOffset>
中,以便将workId
映射到开始时间。
static ConcurrentDictionary<int,DateTimeOffset> starts = new ConcurrentDictionary<int,DateTimeOffset>();
public ActionResult Start(int workId)
{
starts.TryAdd(workId, DateTimeOffset.Now);
return RedirectToAction("Index");
}
public ActionResult Stop(int workId)
{
DateTimeOffset started = DateTimeOffset.MinValue;
if (starts.TryGet(workId, out started))
{
// calculate time difference
}
return View("Index");
}
但是这仍然不是很好,因为你的应用程序可能会被IIS重新启动,你将失去启动值。当不再需要值时,它也没有代码来清理表。你可以通过使用.NET Cache来改进后者,但你真的需要一个数据库才能做到这一点。
答案 1 :(得分:2)
如果您想为所有会话(您通常不想要)共享相同实例,只需将其标记为静态,
private static Stopwatch stopwatch = new Stopwatch();
另外,如果无法从其他控制器/组件访问它,则不必将其定义为公共。
正如@Ian Mercer建议的那样,这不是一个用于秒表的好方法。看一下这些链接: