ASP MVC - Comet/反向 Ajax/PUSH - 此代码线程安全吗?

发布于 2024-08-17 13:07:19 字数 891 浏览 2 评论 0 原文

我正在尝试通过轮询服务器以了解数据变化并保持连接打开直到有内容可以响应来实现彗星风格的功能。

首先,我的控制器上有一个静态变量,它存储数据上次更新的时间:

public static volatile DateTime lastUpdateTime = 0;

因此,每当我轮询的数据发生变化时,该变量就会发生变化。

然后我有一个 Action,它将上次检索数据的时间作为参数:

public ActionResult Push(DateTime lastViewTime)
{
    while (lastUpdateTime <= lastViewTime)
    { 
        System.Threading.Thread.Sleep(10000);
    }
    return Content("testing 1 2 3...");
}

因此,如果 lastUpdateTime 小于或等于 lastViewTime,我们就知道有没有新数据,我们只是将请求保留在循环中,保持连接打开,直到有新信息,然后我们可以将其发送回客户端,客户端将处理响应,然后发出新请求,所以连接基本上始终处于打开状态。

这似乎工作正常,但我担心线程安全,这样可以吗?是否需要将lastUpdateTime标记为易失性?有更好的办法吗?

谢谢

编辑:也许我应该在更新时间值时使用锁定对象

private static object lastUpdateTimeLock = new object();

..

lock (lastUpdateTimeLock)
{
    lastUpdateTime = DateTime.Now;
}

I'm trying to implement comet style features by polling the server for changes in data and holding the connection open untill there is something to response with.

Firstly i have a static variable on my controller which stores the time that the data was last updated:

public static volatile DateTime lastUpdateTime = 0;

So whenever the data i'm polling changes this variable will be changed.

I then have an Action, which takes the last time that the data was retrieved as a parameter:

public ActionResult Push(DateTime lastViewTime)
{
    while (lastUpdateTime <= lastViewTime)
    { 
        System.Threading.Thread.Sleep(10000);
    }
    return Content("testing 1 2 3...");
}

So if lastUpdateTime is less than or equal to the lastViewTime, we know that there is no new data, and we simply hold the request there in a loop, keeping the connection open, untill there is new information, which we could then send back to the client, which would handle the response and then make a new request, so the connection is essentially always open.

This seems to work fine but i'm concerned about thread safety, is this OK? Does lastUpdateTime need to be marked as volatile? Is there a better way?

Thanks

edit: perhaps i should use a lock object when i update the time value

private static object lastUpdateTimeLock = new object();

..

lock (lastUpdateTimeLock)
{
    lastUpdateTime = DateTime.Now;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烧了回忆取暖 2024-08-24 13:07:19

关于您最初的问题,您必须小心 DateTimes,因为它们是 .NET 运行时中的实际对象。只有少数数据类型可以在不加锁的情况下进行本机访问(例如整数、布尔值)(假设您没有使用 Interlocked)。如果您想避免日期时间的任何问题,您可以将刻度作为长整数并使用 Interlocked 类来管理它们。

也就是说,如果您正在 .NET 应用程序中寻找彗星功能,不幸的是,您将不得不比您这里所得到的走得更远。 IIS/ASP.NET 无法按照您现在采用的方法进行扩展;在达到 100 个用户之前,您就会达到限制。除此之外,您必须切换到使用异步处理程序,并为传入请求实现自定义有界线程池。

如果您确实想要一个经过测试的 ASP.NET/IIS 解决方案,请查看 WebSync,它是一个完整的彗星专门为此目的而设计的服务器。

Regarding your original question, you do have to be careful with DateTimes, since they're actual objects in the .NET runtime. Only a few data types can be natively accessed (eg ints, bools) without locking (assuming you're not using Interlocked). If you want to avoid any issues with Datetimes, you can get the ticks as a long and use the Interlocked class to manage them.

That said, if you're looking for comet capabilities in a .NET application, you're unfortunately going to have to go a lot further than what you've got here. IIS/ASP.NET won't scale with the approach you've got in place right now; you'll hit limits before you even get to 100 users. Among other things, you will have to switch to using async handlers, and implement a custom bounded thread pool for the incoming requests.

If you really want a tested solution for ASP.NET/IIS, check out WebSync, it's a full comet server designed specifically for that purpose.

眼角的笑意。 2024-08-24 13:07:19

老实说,我担心的是保持打开的连接数量和空的 while 循环。您的连接可能没问题,但我肯定想做一些负载测试来确定。

while (lastUpdateTime <= lastViewTime) {} 似乎应该有一个 Thread.Sleep(100) 或其中的内容。否则我认为它会不必要地消耗大量的CPU周期。

对我来说,在 lastUpdateTime = DateTime.Now 周围锁似乎没有必要,因为之前的值并不重要。如果是 lastUpdateTime = lastUpdateTime + 1 或其他什么,那么也许就是这样。

Honestly my concern would be with the number of connections kept open and the empty while loop. The connections you're probably fine on, but I'd definitely want to do some load testing to be sure.

The while (lastUpdateTime <= lastViewTime) {} seems like it should have a Thread.Sleep(100) or something in there. Otherwise I'd think it would consume a lot of cpu cycles needlessly.

The lock does not seem necessary to me around lastUpdateTime = DateTime.Now since the previous value does not matter. If it were lastUpdateTime = lastUpdateTime + 1 or something, then maybe it would be.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文