定时器连续循环

Timer Continuous Looping

我正在将信息从计时器传递到另一个函数,但是在信息传递之后,它一直在传递。我不想关闭定时器。 有什么办法可以停止循环吗?定时器间隔为 5 秒。

private static List<DirectoryInfo> list_to_copy = new List<DirectoryInfo>();
DirectoryInfo usbdirectory;
backing_up_interface backing_up_interface;
bool newfilesfound = false;

private void usbchecker_timer_Tick(object sender, EventArgs e)
{ 
    foreach (DriveInfo usbname in DriveInfo.GetDrives().Where(usbproperty => usbproperty.DriveType == DriveType.Removable && usbproperty.IsReady))
    {
        if (!Directory.Exists(AppDomain.CurrentDomain.BaseDirectory.ToString() + usbname.VolumeLabel + @"\"))
        {
            usbdirectory = new DirectoryInfo(usbname.Name);
            if (!list_to_copy.Contains(usbdirectory))
            {
                list_to_copy.Add(usbdirectory);
                newfilesfound = true;
            }
        }
    }
    if (newfilesfound == true)
    {
        process_copy();
        newfilesfound = false;
    }
}

//where information is passed to
private void process_copy()
{
    for (int i = 0; i < list_to_copy.Count; i++)
    {
        backing_up_interface = new backing_up_interface(list_to_copy[i]);
        backing_up_interface.Show(); MessageBox.Show(list_to_copy[i].ToString());
    }
}

if (!Directory.Exists……) {

} 别的 { return; // 阻止循环到达其余代码! }

您可以在 Timer.Tag 属性 中设置一些值,并将其用作标志来控制 Tick 事件中应该发生的事情。

当然需要知道什么时候设置和重置标志..

Tagobject 类型,可以容纳任何东西,包括简单的 int 或漂亮的 Enum..

对于你的情况,我建议至少使用三个状态值:

  • 没有新文件
  • 检测到新文件
  • 正在复制

我会在复制过程中直接从 Tick return;否则检查并在找到新文件时设置标志。

然后在copy方法调用之前设置,在copy方法调用之后重新设置..

但是你想编写什么样的逻辑取决于你。

你实际上正在使用2状态标志;但是复制操作可能需要比预期更长的时间,所以首先要尝试的是在 process_copy(); 之前移动 newfilesfound = false; ..但是有 三个 状态会更好,不无论您将其存储在 class 级别还是使用计时器。

我会为此使用 Microsoft 的 Reactive Extensions (Rx)。它基本上是一种与大量操作员一起创建事件的替代方法,让生活变得非常轻松。

一个运算符是 Observable.Interval,它有效地设置了一个计时器,但它不是在恒定的基础上滴答作响,而是在下一个开始之前的最后一个处理程序代码 运行 之间计时。因此,如果您有 2 秒的间隔,但您的处理需要 X 秒,那么开始之间将有 X + 2 秒的间隔,如果这有意义的话。

Observable
    .Interval(TimeSpan.FromSeconds(5.0))
    .Subscribe(_ =>
    {
        foreach (DriveInfo usbname in DriveInfo.GetDrives().Where(usbproperty => usbproperty.DriveType == DriveType.Removable && usbproperty.IsReady))
        {
            if (!Directory.Exists(AppDomain.CurrentDomain.BaseDirectory.ToString() + usbname.VolumeLabel + @"\"))
            {
                usbdirectory = new DirectoryInfo(usbname.Name);
                if (!list_to_copy.Contains(usbdirectory))
                {
                    list_to_copy.Add(usbdirectory);
                    newfilesfound = true;
                }
            }
        }
        if (newfilesfound == true)
        {
            process_copy();
            newfilesfound = false;
        }
    });

仅 NuGet "Rx-Main".

如果找不到该文件,请创建一个目录。它会阻止它循环。

它一直在循环,因为该目录不存在,所以如果找不到该目录,我让它创建一个新目录。这阻止了它循环。

private static List<DirectoryInfo> list_to_copy = new List<DirectoryInfo>();
DirectoryInfo usbdirectory;
backing_up_interface backing_up_interface;
bool newfilesfound = false;

private void usbchecker_timer_Tick(object sender, EventArgs e)
{ 
    foreach (DriveInfo usbname in DriveInfo.GetDrives().Where(usbproperty => usbproperty.DriveType == DriveType.Removable && usbproperty.IsReady))
    {
        if (!Directory.Exists(AppDomain.CurrentDomain.BaseDirectory.ToString() + usbname.VolumeLabel + @"\"))
        {
            Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory.ToString() + usbname.VolumeLabel + @"\");
            usbdirectory = new DirectoryInfo(usbname.Name);
            if (!list_to_copy.Contains(usbdirectory))
            {
                list_to_copy.Add(usbdirectory);
                newfilesfound = true;
            }
        }
    }
    if (newfilesfound == true)
    {
        process_copy();
        newfilesfound = false;
    }
}

//where information is passed to
private void process_copy()
{
    for (int i = 0; i < list_to_copy.Count; i++)
    {
        backing_up_interface = new backing_up_interface(list_to_copy[i]);
        backing_up_interface.Show(); MessageBox.Show(list_to_copy[i].ToString());
    }
}