Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在C中每天激活一次线程#_C#_.net_Wpf_Multithreading_Timer - Fatal编程技术网

C# 如何在C中每天激活一次线程#

C# 如何在C中每天激活一次线程#,c#,.net,wpf,multithreading,timer,C#,.net,Wpf,Multithreading,Timer,我有一个WPF应用程序,它的任务是导致旧订单过期。导致订单过期的线程需要每天运行一次。我现在有下面的代码来完成我想要完成的任务(对代码做了一些简化) 我的问题是我的方法是否合理,或者是否有更好的方法来完成任务 有没有办法让线程等待一天的变化?这是一个好的解决方案吗 我使用的线程类型是否最适合此工作 使用系统线程; 公共类日常任务 { 公共静态void StartJob() { while(true) { 字符串lastRunFile=“lastRun.txt”; //获取上次写入文件的时间 Da

我有一个WPF应用程序,它的任务是导致旧订单过期。导致订单过期的线程需要每天运行一次。我现在有下面的代码来完成我想要完成的任务(对代码做了一些简化)

我的问题是我的方法是否合理,或者是否有更好的方法来完成任务

有没有办法让线程等待一天的变化?这是一个好的解决方案吗

我使用的线程类型是否最适合此工作

使用系统线程;
公共类日常任务
{
公共静态void StartJob()
{
while(true)
{
字符串lastRunFile=“lastRun.txt”;
//获取上次写入文件的时间
DateTime lastRunTime=new System.IO.FileInfo(lastRunFile.LastWriteTime;
//获取自上次运行以来的时间跨度
TimeSpan SincelasRuntime=DateTime.Today-lastRunTime.Date;
//如果一天过去了
如果(sinceLastRunTime.Days>=1)
{
//向文件写入任何内容以更新lastWriteTime
System.IO.File.writealText(lastRunFile,DateTime.Now.ToString());
//做好这项工作
DoStuff();
}
其他的
{
//睡一小时
线程睡眠(1000*60*60);
}
}
}
私有静态void DoStuff(){
//做日常工作
}
}
我使用以下命令启动线程:

Thread thr=新线程(DailyTask.StartJob);
thr.Start();

您可以使用
系统.Threading.Timer
类。计时器构造函数具有
period
参数,该参数指定调用回调的周期。参见这里的示例

您可以调用
DoStuff()
方法作为回调。 这是更好的解决方案,因为它避免了线程休眠

您还可以使用事件等待句柄(AutoResetEvent)。看

比如:

var currenTime = DateTime.Now;
var nextDay = currenTime.AddDays(1);
var periodTillEndOfTheDay = nextDay.Date - currenTime;
var timer = new Timer(x => {DoStuff()}, null, TimeSpan.Zero, periodTillEndOfTheDay);

下面的代码片段可以帮助您

using System.Timers;

        const double intervalinMilliseconds = 86400000; // 1 day in milliseconds

        Timer Timeinterval = new Timer(intervalinMilliseconds);
        Timeinterval.Elapsed += new Dostuff();
        Timeinterval.Enabled = true;

 public void Dostuff(object sender, ElapsedEventArgs e)
    {

    }

有很多作业调度工具/库,当然还有更好的方法,例如使用Windows任务调度程序每小时(或新的一天,例如上午12点)调度一个作业,因此您根本不需要while循环。但我的哲学是“如果它起作用,它就起作用”。我现在看到你的实现有很多错误,但是正如你所说的,你已经做了“简化”,所以除非你发布真正的代码,否则没有必要详细说明。如果你不想使用特殊的调度库,你应该考虑使用一个类似于<代码> DexChutier-<代码>的东西,这将与WPF的UI友好。甚至是来自
系统线程
命名空间的常规
计时器
。@JEL,在另一个线程中启动程序很好,因此使用
thr.start()
也很好。您还可以使用更现代的
任务。运行
。我还将对您的代码进行以下改进。1) 检查lastRun.txt文件是否存在,否则lastRunTime可能无效。2) 如果另一个进程正在使用lastRun.txt,因此您无法读取/写入它,则捕获异常。3) 您的Thread.Sleep仅存在于ELSE条件中,这意味着如果您满足if条件,您将“完成工作”,然后立即循环回WHILE循环,而不需要睡眠一个小时。
Thread.Sleep(TimeSpan.FromHours(1))
可能更具可读性即使您必须使用如此难看的构造,您也应该在WPF应用程序中使用
DispatchTimer
,而不是
System.Threading.Timer
。虽然在问题中提到应用程序是WPF应用程序,但要执行的工作似乎是后台工作。所以定时器也可以。System.Timers.Timer在与用户界面(UI)线程不同的线程上运行。为了访问用户界面(UI)线程上的对象,有必要将操作发布到用户界面(UI)线程的调度程序上。