自动倒计时器来调整数据库记录

时间:2012-11-30 12:05:02

标签: c# database asp.net-mvc-3 countdowntimer visual-web-developer-2010

我有一个小型的MVC网站,这是一个朋友美发沙龙。在这个页面上,我有一个div,用于显示从数据库记录中获取的数字。这个数字是当前排队等待理发的人数。

我目前能够登录“管理”页面并使用表格更新此号码,从“2”更改为“5”,然后将“5”更改为“6”,具体取决于有多少人正坐在这个队列中。

这是目前的手动操作。代码如下:

=============================

控制器

[HttpPost]
        public ActionResult Update(Data data)
        {
            if (ModelState.IsValid)
            {
                data.ID = 1; //EF need to know which row to update in the database. 
                db.Entry(data).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index", "Home");
            }

            return View(data);
        }

====================================

型号代码

{
    public class Data
    {
        public int ID { get; set; }
        public string Queue_Number { get; set; }
    }

    public class DataDBContext : DbContext
    {
        public DbSet<Data>Queue { get; set; }
    }
}

我真正希望发生的是,一旦您从“管理”页面上的表单手动更新了队列号,我就要自动倒计时20分钟(理发所需的大致时间)然后将队列号自动调整为1,直到达到“0”。

e.g。队列中有5个人,20分钟后自动调整为4个人,网页会自动更新/刷新,然后又有2个人走进去,所以我们手动将其调整为队列中的6个人,计时器再次启动,每20分钟通过队列调整-1直到它下降到“0”。一旦达到“0”,它就会一直停留在那里,直到我们手动将更多人添加到队列中。

我恐怕我不知道如何开始提出这样的要求,或者即使有可能?

我非常感谢这里的专家提供的任何帮助,这些帮助可以为我“babystep”。我没有提供的任何信息我会努力补充 - 我意识到我不是最好的解释自己: - (

4 个答案:

答案 0 :(得分:7)

你考虑过Ajax吗?你在手动设置标志时存储最后更新的时间吗?您可以使用Ajax请求同时使用jquery Set interval运行。这将每2分钟触发一次ajax请求。查找最后一次更新,如果超过20分钟,然后从数据库中删除一个,则返回将是新号码,jquery可以为您更新该号码。

实际上这是一个非常简单的过程,但需要有关基础数据的更多细节。

以下是我可以从您的问题中看到它的方法

在控制器中

public ActionResult ajaxUpdate()
        {
            //open connection
            dbcontext db = new dbcontext();
            db.Connection.Open();

            // get the last updated record in the database.
            var entry = db.Entry.OrderByDecending(m=> m.LastUpdatedDate).FirstOrDefault();

            //clean up
            db.Connection.Close();
            db.Dispose();

            //return -1 as error
            if(entry == null){

                return Json(-1,JsonRequestBehavior.AllowGet);

            }

            // get current number of people in queue
            Int32 numberOfPeople = entry.QueueNumber;

            TimeSpan span = DateTime.Now.Subtract(entry.LastUpdatedDate);

            if(span.Minutes >= 20){

                // if 20 mins have passed assume a person has been completed since manual update
                numberOfPeople--;

            }

            //this returns a number, alternatively you can return a Partial
            return Json(numberOfPeople, JsonRequestBehavior.AllowGet);
        }

Jquery和Ajax

$(document).ready(function () {

    // run function every x minutes
    setInterval(function () {
        UpdateQueue();
    }, 100000);





});
    function UpdateQueue() {

    $.ajax({
        cache: true,
        type: 'POST',
        url: "/ControllerName/ajaxUpdate",
        async: false,
        dataType: "json",
        success: function (result) {
            // on success result will be the number returned

            // -1 is error
            if (result == -1) {
                return;

            }

            // check the -- didn't return a negative
            if (result < 0) {

                result = 0;

            }

            //find your element in the HTML to update
            $('#NumberElement').text().replaceWith(result);


        }

    });


}

在包含此代码之前,必须确保包含jquery库,否则将无法定义Jquery。

答案 1 :(得分:4)

我已经通过一点线程弥补了服务器端解决方案。希望我对关键部分锁是正确的。

它的优势在于,您的应用程序管理员不必挂在页面上以降低当前客户的数量(如他应该使用ajax请求)。

工作原理

在“客户数量”更新时,它启动(如果需要)新的倒计时线程,它等待(休眠)预定义的间隔,然后减少数量。

public class CustomerAdminService
{
    // time in milliseconds it will take to decrease number of waiting customers 
    const int sleepTime = 10000;
    // current number of customers (just for simplicity - you can have it in db or somewhere else)
    static int numberOfCustomers;

    static Thread updaterThread;

    // object lock
    static readonly object locker = new Object();

    public int GetNumberOfCustomers()
    {
        return numberOfCustomers;
    }

    public void UpdateCustomers(int value)
    {
        lock (locker)
        {
            if (updaterThread == null)
            {
                //start new downcounting thread
                updaterThread = new Thread(new ThreadStart(UpdateWorker));
                updaterThread.Start();
            }
            SetNumberOfWaitingCustomers(value);
        }
    }

    private void SetNumberOfWaitingCustomers(int value)
    {
        numberOfCustomers = value;
    }

    // downcounting thread method
    private void UpdateWorker()
    {      
        while (true)
        {
            // sleep for predefined time
            Thread.Sleep(sleepTime);
            lock (locker)
            {              
                var number = GetNumberOfCustomers();             
                if (number <= 1)
                {
                    // if number of currents customers is now zero - end the downcounting thread
                    SetNumberOfWaitingCustomers(0);
                    updaterThread = null;
                    return;
                }
                SetNumberOfWaitingCustomers(number - 1);
            }
        }
    }
}

评论:您可以考虑将jQuery用于某些计时器缩减计数脚本。显示类似的内容:您可以在40分钟内完成服务; - )

答案 2 :(得分:1)

是Ajax是关键。您的网站可以使用它与您的服务器进行不明显的通信。

答案 3 :(得分:1)

另一种方法是不更新数据库中的计数,而只是使用查询来确定特定时间段内的客户数量。您可以通过修改模型来执行此操作,以便代替QueueNumber使用到达时间并更改控制器,以便插入新的数据记录。

{
    public class Data
    {
        public int ID { get; set; }
        public DateTime Arrival_Time { get; set; }
    }

    public class DataDBContext : DbContext
    {
        public DbSet<Data> Queue { get; set; }
    } 
}

这样,正如其他人所建议的那样,您可以使用AJAX轮询队列中的人数,其控制器操作可能如下所示:

[HttpGet]
public ActionResult NumberOfPeopleInQueue()
{
    var result = db.NumberOfCustomersSince(DateTime.Now.AddMinutes(-20));
    return Json(result);
}

这种方法的好处是,如果理发开始花费更长时间(比如说30分钟),您只需更改查询,应用程序就可以继续工作。