Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.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#_.net_Winforms_Timer - Fatal编程技术网

C# 运行并停止一个方法一分钟

C# 运行并停止一个方法一分钟,c#,.net,winforms,timer,C#,.net,Winforms,Timer,MyMethodName() -有一个用于90000个条目的for循环(以及该for循环中的一些验证) for(int i=0;i两件事。首先,计时器代码实际上没有连接到运行MyMethodName。计时器设计用于在时间过去时运行进程(可能是以固定的间隔,具体取决于设置方式) 第二,也是更重要的一点,要中止循环,您必须在循环中放入代码。关键是在循环之前有一个秒表或类似的开始,然后在循环开始时检查经过了多少时间。如果是一分钟或更长,则中断; 需要注意的关键是,您不会在一分钟内完全停止,但会在一分钟

MyMethodName()

-有一个用于90000个条目的for循环(以及该for循环中的一些验证)


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();
        }
    }
}