C# 让MessageBox出现一次(计时器内的代码)

C# 让MessageBox出现一次(计时器内的代码),c#,c#-4.0,C#,C# 4.0,更新:我已经设法解决了我的问题。使用下面的代码,我在保存XML后移动了MessageBox,并将计时器从100ms更改为400ms。我现在有一个盒子出现了,感谢上帝。尽管任何人都有更新列表数组(ActListTask)中单个值(actAlerted)的捷径,但知道这一点很好 我在显示MessageBox时遇到了一个小问题。显示在一个计时器内,而不向我发送垃圾邮件。以下是我一直在使用的代码部分: public class ActiveTasks { //Properties

更新:我已经设法解决了我的问题。使用下面的代码,我在保存XML后移动了MessageBox,并将计时器从100ms更改为400ms。我现在有一个盒子出现了,感谢上帝。尽管任何人都有更新列表数组(ActListTask)中单个值(actAlerted)的捷径,但知道这一点很好

我在显示MessageBox时遇到了一个小问题。显示在一个计时器内,而不向我发送垃圾邮件。以下是我一直在使用的代码部分:

public class ActiveTasks
    {
        //Properties here
    }

public List<ActiveTasks> ActTaskList = new List<ActiveTasks>();

for (int i = 0; i < ListActive.Items.Count; i++)
        {
            if (DTime.Date == newDateTime.Date)
            {
                if (newDateTimeLeft.CompareTo(TimeSpan.Zero) <= 0 && ActTaskList[i].ActReminded != "true")
                {
                    MessageBox.Show("!!!!");
                    ActTaskList.Add(new ActiveTasks()
                    {
                        ActTitle = ActTaskList[i].ActTitle,
                        ActDesc = ActTaskList[i].ActDesc,
                        ActDate = ActTaskList[i].ActDate,
                        ActTime = ActTaskList[i].ActTime,
                        ActStatus = ActTaskList[i].ActStatus,
                        ActReminded = "true",
                        ActRepeat = ActTaskList[i].ActRepeat
                    });

                    ListActive.Items.RemoveAt(i);

                    ActTaskList.RemoveAt(i);

                    XDocument XmlActTasks = GenerateActiveListToXML(ActTaskList);
                }
            }
        }
公共类活动任务
{
//这里的财产
}
public List ActTaskList=新列表();
对于(int i=0;i如果(newDateTimeLeft.CompareTo)(TimeSpan.Zero)您可以这样做吗

Action message = () => MessageBox.Show("!!!!!!!!!!!!!"));
object lockOb = new object();

void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    lock(lockOb)
        if(null != message)
        {
            message();
            message = null;
        }
}

当前时间与循环中发生的第二个时间完全一致的几率很小。为什么不将newDateTime视为一个分界点并设置一个标志呢

//Declare this outside of the loop
bool hasDisplayed = false;

//Inside the timer event handler
if (!hasDisplayed && DateTime.Now >= newDateTime)
{
    hasDisplayed = true;

    MessageBox.Show("!!!!!!!!!!!!!");
}

您说您已经尝试了一个布尔值,指示消息已经显示,我假设是因为代码可能与下面的代码类似

void TimerLoop()
{
    bool msgAlreadyShown;

    if(!msgAlreadyShown)
    {
        MessageBox.Show("!!!!!!!");
    }
    // Other work in your timer function
}
该代码的问题在于,每次计时器调用函数时,bool都会设置为false。虽然您没有发布太多代码,但至少已经说明了您要完成的任务,一个检查是否应该向用户显示提醒的计时器

我将对您如何组合软件进行一些疯狂的猜测,很有可能它已经过时了,但我希望它可能会为您指明正确的方向。您可以有一些类似这样的提醒课程:

public class Reminder
{
    string Message { get; set;}
    DateTime Alarm { get; set; } 
    bool IsDismissed { get; set; }
}
我假设您可能希望在计时器循环中检查多个提醒,因此您的计时器循环可能类似于:

private List<Reminder> _activeReminders; // A list of reminders

void TimerLoop(object s, ElapsedEventArgs e)
{
    lock(_activeReminders) 
    {
        var now = DateTime.Now;
        foreach(var reminder in _activeReminders)
        {
            // only run this code if the time has passed and it hasn't already
            // been shown
            if(now.CompareTo(reminder.Alarm) >= 0 && !reminder.IsDismissed)
            {
                MessageBox.Show(reminder.Message);
                reminder.IsDismissed = true;
            }
        }
    }
}
private List\u activemembers;//提醒列表
void TimerLoop(对象s、ElapsedEventArgs e)
{
锁定(\u活动提醒)
{
var now=DateTime.now;
foreach(活动提醒中的var提醒)
{
//仅当时间已经过去而尚未结束时才运行此代码
//展示
如果(now.CompareTo(remention.Alarm)>=0&&!remention.isdissed)
{
MessageBox.Show(提醒.消息);
remention.ismissed=true;
}
}
}
}
这是一个相当幼稚的实现,因为您可能不想永远保留提醒,并且提醒永远不会从
\u activemembers
列表中删除,但您实际上只需要添加某种状态来确定提醒是否已经显示

当然,这也不是一个完整的例子,因为我从来没有更新过
\u activememberments
字段或向其添加任何内容,但我认为这可能有助于了解您需要做什么。此外,您可能不关心多个提醒,并且您的计时器代码可能与此完全不同。主要的想法是向您展示如何使用它可以跟踪提醒的状态,并根据自己的代码进行调整。以上只是一个示例


另外,我还没有实际测试过它,所以将其视为伪代码,而不是其他任何东西。然而,逻辑是正确的,它应该只导致消息框出现一次。

您在哪里编写声明计时器的代码?您使用的是哪种类型的计时器?使用
bool
,当用户出现时,将
bool
设置为false,只有当
bool
为真时才发出警报。你想做什么?从声音上看,你想在一定的延迟后得到一个messagebox。这就是你想要的吗?你有没有尝试过“if(Date.Equals(newDateTime))?@p4bl0:这没有帮助。它仍然比较
滴答声(这不是Java
;)
)这只会让messagebox向我发送垃圾邮件。我编辑并添加了一个锁。这确实是你的问题,因为“确定”按钮等待你返回,它永远不会被设置为null。但是有了锁,它在锁退出之前不会再次检查消息。你的更新无法修复它。请给我一点时间,我将更新我的原始问题。是否继续您希望消息框在延迟时间后或时间满足某个值时显示?我希望它显示值彼此相等的时间,请检查我的问题,我已经更新了它。希望它能帮助您了解我在做什么。这有点帮助。因为我已经有一些列表,我只是在clas中添加了另一个公共字符串s(因为我现在懒得弄清楚如何从XML中读取bool)。但是,它并不能阻止对Messagebox的垃圾邮件。@MattVon-那么你的问题可能存在于其他地方,或者你没有将上面的代码完全翻译成现在的样子来使用你的应用程序。我只是测试了上面的代码,它不会向我发送垃圾邮件。如果你解除了对
\u activeemminders
的锁定,计时器可能会自动关闭e在代码执行时再次执行
MessageBox.Show()
,因为它(可能)会阻塞线程。在这种情况下,您需要在显示MessageBox之前将
IsDismissed
设置为true。除此之外,如果不实际查看您的代码,我不确定我能帮上什么忙。