在C#中延迟执行SQL查询

时间:2013-11-11 10:36:01

标签: c# asp.net sql

我正在开发一款游戏。在这个游戏中玩家可以点击按钮攻击老板,他必须等待5分钟才能获得攻击结果。攻击只在5分钟后执行。
所以这是我的尝试: 这是我在单击按钮时调用的函数:

public static void InsertNewWaitingAttack(string attacker_id, string boss_id, DateTime  start, DateTime done)
{
    string sql = "INSERT INTO WaitingAttacks (AttackerID,BossID,AttackTime,DoneTime) VALUES (@A_ID,@B_ID,@Start,@Done); ";
    sql += "WAITFOR DELAY '000:05:00'; ";
    sql += "INSERT INTO BossAttacks (AttackerID,BossID,AttackTime,Damage) VALUES (@A_ID,@B_ID,@Start,@Damage); ";
    sql += "DELETE FROM WaitingAttacks WHERE AttackerID=@A_ID AND AttackTime=@Start;";
    SqlConnection sc = new SqlConnection(conString);
    using (SqlCommand cmd = new SqlCommand(sql, sc))
    {
        cmd.Parameters.AddWithValue("A_ID", attacker_id);
        cmd.Parameters.AddWithValue("B_ID", boss_id);
        cmd.Parameters.AddWithValue("Start", start);
        cmd.Parameters.AddWithValue("Done", done);
        cmd.Parameters.AddWithValue("Damage", 500);
        sc.Open();
        cmd.ExecuteNonQuery();
        sc.Close();
    }
}

但是当我调用此函数时,我收到以下错误:

  

超时已过期。操作完成之前经过的超时时间或服务器没有响应。

编辑:为了澄清我的问题,这是一个asp.net应用程序。解决方案应该考虑服务器应该为多个客户端提供服务。
如果用户在执行攻击之前进入“结果页面”,他将看到执行攻击的倒计时。(这意味着应该始终可以访问攻击的开始时间。)
编辑#2:
这个问题仍然有用。我还没有找到任何解决方案。

2 个答案:

答案 0 :(得分:4)

如何在代码中设置一个在5分钟后触发的计时器并执行INSERT而不是WAITFOR?这样,程序仍然保持响应,你仍然会有延迟。

我建议你使用System.Timers.Timer,因为它在一个单独的线程中运行,也可以更容易地配置为“一次性”计时器。


另一种可能使处理多个boss附件更容易的方法是创建一个待处理的“boss攻击”列表,并在该列表上使用线程计时器,如下所示:

private class BossAttack
{
    public DateTime AttackTime;
    //... Other properties
}

List<BossAttack> pendingAttacks = new List<BossAttack>();

// Adding a boss attack
lock (pendingAttacks)
{
    pendingAttacks.Add(new BossAttack()
    {
         AttackTime = DateTime.Now;
         ...
    }
}

计时器可以每秒运行一次,让所有老板攻击超过5分钟并处理它们:

var currentAttacks = (from a in pendingAttacks where (DateTime.Now - a.AttackTime).TotalMinutes() >= 5 select a);
foreach (var currentAttack in currentAttacks)
    //...

答案 1 :(得分:-2)

您可以在异步中尝试System.Threading.Sleep为什么会在这里看到答案:

Asynchronous Thread.Sleep()