2017-07-22 50 views
0

我即将建立报警系统。它的工作方式是通过从gridview列中提取日期/时间信息,然后使用异步操作来检查现在时间是否等于gridview日期/时间列中的一个或多个行,如果是,则显示一个警报。C#报警系统回路问题

一切正常,到目前为止,除了当2行包含相同的日期/时间,报警将触发4次,而不是2.这是我走到这一步:

string firma = ""; 
    private void radButton1_Click(object sender, EventArgs e) 
    { 
     try 
     { 
      for (int i = 0; i < radGridView4.Rows.Count; i++) 
      { 
       DateTime executionTime = Convert.ToDateTime(radGridView4.Rows[i].Cells[10].Value.ToString()); 
       ScheduleAction(action, executionTime); 
      } 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex); 
     } 
    } 

    public async void ScheduleAction(Action action, DateTime ExecutionTime) 
    { 
     try 
     { 
      if (DateTime.Now < ExecutionTime)//ExecutionTime only create an alarm for rows that are later than now 
      { 
       await Task.Delay((int)ExecutionTime.Subtract(DateTime.Now).TotalMilliseconds); 

       action(); 
      } 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex); 
     } 
    } 

    public void action() 
    { 
     RadDesktopAlert Alert; 
     for (int i = 0; i < radGridView4.Rows.Count; i++) 
     { 
      DateTime executionTime = Convert.ToDateTime(radGridView4.Rows[i].Cells[10].Value.ToString()); 

      if (DateTime.Now.Date == executionTime.Date && DateTime.Now.Hour == executionTime.Hour && DateTime.Now.Minute == executionTime.Minute) 
      { 
       Alert = new RadDesktopAlert(); 

       firma = radGridView4.Rows[i].Cells[2].Value.ToString(); 

       Alert.CaptionText = "Telefonmøde"; 
       Alert.ContentText = firma; 
       Alert.Show(); 

      } 
     } 
    } 

任何帮助赞赏,并且没有try语句也没有错误。

在此先感谢!问题的

回答

1

部分是,你调度重复报警,另一部分是你的行动是要还触发重复报警,因为无论这些代码块是通过网格循环。

如果action方法不依赖于网格中的数据,而是通过它的参数获取它需要的所有内容,它可能会有所帮助。这意味着我们应该首次捕获content,通过网格项目循环,然后将此信息传递给方法。

要做到这一点,我们可以修改action方法为内容取一个字符串,我们可以删除网格的循环。需要注意的是,如果我们现在称之为action,它只会执行动作向右走,所以它是由主叫方在正确的时间来安排吧:

public void action(string content) 
{ 
    var alert = new RadDesktopAlert 
    { 
     CaptionText = "Telefonmøde", 
     ContentText = content 
    }; 

    alert.Show(); 
} 

现在,我们已经修改了action方法,我们也需要修改ScheduleAction方法,以便它传递新的必需参数。这意味着它也将需要采取新的参数:

public async void ScheduleAction(Action<string> action, string content, 
    DateTime ExecutionTime) 
{ 
    if (DateTime.Now < ExecutionTime) 
    { 
     await Task.Delay((int)ExecutionTime.Subtract(DateTime.Now).TotalMilliseconds); 
     action(content); 
    } 
} 

接下来,我们可以创建一个单独的List<DataTime>对象来跟踪我们已经计划时代。然后,当我们循环浏览网格视图时,如果它不在列表中,我们只安排时间。我们也捕捉到content数据,而我们在这:

var scheduledExecutionTimes = new List<DateTime>(); 

for (int i = 0; i < radGridView4.Rows.Count; i++) 
{ 
    DateTime executionTime = Convert.ToDateTime(radGridView4.Rows[i].Cells[10].Value.ToString()); 

    if (!scheduledExecutionTimes.Contains(executionTime)) 
    {    
     string content = radGridView4.Rows[i].Cells[2].Value.ToString(); 
     ScheduleAction(action, content, executionTime); 

     // Add this time to our list 
     scheduledExecutionTimes.Add(executionTime); 
    } 
} 
+0

我想这块代码应该在按钮右边? var scheduledExecutionTimes = new List (); for(int i = 0; i Taco2

+0

问题是我需要它支持相同的日期/时间值,但是只能再次显示报警,您的代码很鼓舞人心,但是我们可以以某种方式做到这一点,以支持我的需求吗? – Taco2

+0

在研究完你的代码后,我意识到我可以删除if(!scheduledExecutionTimes.Contains(executionTime))行来实现我想要的。非常感谢很多人一直在为此工作数日! – Taco2

0

你可以把break调用Alert.Show()后:

public void action() 
{ 
    RadDesktopAlert Alert; 
    for (int i = 0; i < radGridView4.Rows.Count; i++) 
    { 
     DateTime executionTime = Convert.ToDateTime(radGridView4.Rows[i].Cells[10].Value.ToString()); 

     if (DateTime.Now.Date == executionTime.Date && DateTime.Now.Hour == executionTime.Hour && DateTime.Now.Minute == executionTime.Minute) 
     { 
      Alert = new RadDesktopAlert(); 

      firma = radGridView4.Rows[i].Cells[2].Value.ToString(); 

      Alert.CaptionText = "Telefonmøde"; 
      Alert.ContentText = firma; 
      Alert.Show(); 
      break; // This will prevent duplicate alarms 
     } 
    } 
} 
+0

它仍然显示重复,但现在它只显示1行。请注意,action()本身在循环内,女巫是问题 – Taco2

0

我发现@Rufus L的解决方案非常有用的,唯一的变化我做的这3个代码块将删除if(!scheduledExecutionTimes.Contains(executionTime))以实现我的目标。希望这对其他人有用,因为这对我来说是一场斗争。

var scheduledExecutionTimes = new List<DateTime>(); 

for (int i = 0; i < radGridView4.Rows.Count; i++) 
{ 
    DateTime executionTime = Convert.ToDateTime(radGridView4.Rows[i].Cells[10].Value.ToString()); 

    if (!scheduledExecutionTimes.Contains(executionTime)) 
    {    
     string content = radGridView4.Rows[i].Cells[2].Value.ToString(); 
     ScheduleAction(action, content, executionTime); 

     // Add this time to our list 
     scheduledExecutionTimes.Add(executionTime); 
    } 
} 

谢谢!