C# 运行并停止一个方法一分钟
MyMethodName() -有一个用于90000个条目的for循环(以及该for循环中的一些验证)C# 运行并停止一个方法一分钟,c#,.net,winforms,timer,C#,.net,Winforms,Timer,MyMethodName() -有一个用于90000个条目的for循环(以及该for循环中的一些验证) for(int i=0;i两件事。首先,计时器代码实际上没有连接到运行MyMethodName。计时器设计用于在时间过去时运行进程(可能是以固定的间隔,具体取决于设置方式) 第二,也是更重要的一点,要中止循环,您必须在循环中放入代码。关键是在循环之前有一个秒表或类似的开始,然后在循环开始时检查经过了多少时间。如果是一分钟或更长,则中断; 需要注意的关键是,您不会在一分钟内完全停止,但会在一分钟
for(int i=0;i两件事。首先,计时器代码实际上没有连接到运行MyMethodName
。计时器设计用于在时间过去时运行进程(可能是以固定的间隔,具体取决于设置方式)
第二,也是更重要的一点,要中止循环,您必须在循环中放入代码。关键是在循环之前有一个秒表或类似的开始,然后在循环开始时检查经过了多少时间。如果是一分钟或更长,则中断;
需要注意的关键是,您不会在一分钟内完全停止,但会在一分钟结束时完成正在运行的循环的迭代,然后停止。这通常是您想要的,因为中途停止处理可能会导致严重的副作用
for (int i = 0; i <= 90000; i++)
{
//validations go here
}
秒表秒表=新秒表();
秒表。开始();
对于(int i=0;它的跨度为秒(5))
打破
控制台写入线(i);
睡眠(1000);
}
<> >注意<代码>线程。睡眠< /代码>只是因为我太快地通过了所有90000个迭代。.-)/p>所以你可能需要一个非常不同的实现。考虑一下:
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for (int i =0; i<=90000; i++)
{
if (stopwatch.Elapsed>TimeSpan.FromSeconds(5))
break;
Console.WriteLine(i);
Thread.Sleep(1000);
}
但是,您可以让它更加健壮。您可以这样打发时间:
_worker.RunWorkerAsync();
public static void RunTimedAction(Action<CancellationToken> action, TimeSpan timeout)
{
using (var cancellationTokenSource = new CancellationTokenSource(timeout))
action(cancellationTokenSource.Token);
}
private void action(CancellationToken cancel)
{
int i;
for (i = 0; i < 1000000; ++i)
{
if (cancel.IsCancellationRequested)
break;
Thread.Sleep(10); // Simulate work.
}
Console.WriteLine("action() reached " + i);
}
然后在DoWork
处理程序中,执行以下操作:
_worker.RunWorkerAsync(60000);
因此,如有必要,您可以这样做:
while (timer.ElapsedMilliseconds < (int)args.Argument && !_worker.CancellationPending)
嗯,用秒表代替
_worker.CancelAsync();
秒表秒表=新秒表();
秒表。开始();
对于(int i=0;i=60)
打破
}
然而,上面的计时器代码一直执行到所有90000条记录都在for循环中循环完成,不知何故,该方法一分钟都没有运行?有帮助吗
在释放UI线程之前,计时器不会引发事件,而释放UI线程直到方法完全完成后才会发生
如果要防止方法运行超过特定的持续时间,可以直接在方法中处理:
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
for(int i= 0; i <= 90000; i++)
{
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = stopWatch.Elapsed;
if(ts.Seconds >= 60)
break;
}
然后,在您的方法中:
MyMethodName(TimeSpan.FromMinutes(1));
void MyMethodName(TimeSpan maxRuntime)
{
DateTime expiration=DateTime.Now+maxRuntime;
for(int i=0;i过期)
打破
}
}
}
也就是说,更好的方法是将其推送到后台线程中,并根据需要取消。您可以在验证中设置一个标志,通过将事件处理程序连接到计时器对象中的Tick事件来查看是否完成
void MyMethodName(TimeSpan maxRuntime)
{
DateTime expiration = DateTime.Now + maxRuntime;
for (int i = 0; i <= 90000; i++)
{
//validations go here
if (i % 100 == 0) // check every 100?
{
if (DateTime.Now > expiration)
break;
}
}
}
你的原始代码在哪里
//in an area accessible to
//both elements
object readonly _lock = new object();
bool elapsed = false;
MyMethodName的内部
elapsed = false;
timer1= new System.Windows.Forms.Timer();
timer1.Interval =60000; // 1 min
timer1.Tick=((sender, everntArgs)=>
{
lock(_lock)
elapsed = true;
});
timer1.Start();
MyMethodName();
timer1.Stop();
//在循环中
对于(int i=0;i如果将CancellationTokenSource
与构造函数一起使用,则可以轻松编写在指定时间后取消操作的方法
您可以这样编写一个方法:
//inside the loop
for (int i = 0; i <= 90000; i++)
{
//validations go here
lock(_lock)
if(elapsed)
break;
}
您可以这样使用:
_worker.RunWorkerAsync();
public static void RunTimedAction(Action<CancellationToken> action, TimeSpan timeout)
{
using (var cancellationTokenSource = new CancellationTokenSource(timeout))
action(cancellationTokenSource.Token);
}
private void action(CancellationToken cancel)
{
int i;
for (i = 0; i < 1000000; ++i)
{
if (cancel.IsCancellationRequested)
break;
Thread.Sleep(10); // Simulate work.
}
Console.WriteLine("action() reached " + i);
}
让我们将其整合到一个完整的演示程序中:
Console.WriteLine("Started at " + DateTime.Now);
RunTimedAction(action, TimeSpan.FromSeconds(10));
Console.WriteLine("Stopped at " + DateTime.Now);
使用系统;
使用系统线程;
名称空间演示
{
班级计划
{
无效运行()
{
Console.WriteLine(“开始于”+DateTime.Now);
RunTimedAction(操作,时间跨度从秒(10));
Console.WriteLine(“在“+DateTime.Now”处停止);
}
私有作废操作(取消令牌取消)
{
int i;
对于(i=0;i<1000000;++i)
{
如果(取消。已请求取消安装)
打破
Thread.Sleep(10);//模拟工作。
}
Console.WriteLine(“操作()到达”+i);
}
公共静态void RunTimedAction(操作操作,TimeSpan超时)
{
使用(var cancellationTokenSource=new cancellationTokenSource(超时))
操作(cancellationTokenSource.Token);
}
静态void Main()
{
新程序().run();
}
}
}
我不确定您是否真的需要那里的锁。考虑到在循环的注释中有关于验证的讨论,是否在不注意效果的情况下采用此异步(例如,以下代码将在分钟结束前运行)?
using System;
using System.Threading;
namespace Demo
{
class Program
{
void run()
{
Console.WriteLine("Started at " + DateTime.Now);
RunTimedAction(action, TimeSpan.FromSeconds(10));
Console.WriteLine("Stopped at " + DateTime.Now);
}
private void action(CancellationToken cancel)
{
int i;
for (i = 0; i < 1000000; ++i)
{
if (cancel.IsCancellationRequested)
break;
Thread.Sleep(10); // Simulate work.
}
Console.WriteLine("action() reached " + i);
}
public static void RunTimedAction(Action<CancellationToken> action, TimeSpan timeout)
{
using (var cancellationTokenSource = new CancellationTokenSource(timeout))
action(cancellationTokenSource.Token);
}
static void Main()
{
new Program().run();
}
}
}