秒表与Task.Wait

时间:2016-05-30 13:01:24

标签: c# .net multithreading task stopwatch

注意:我被限制为.net 4.0

我目前正在使用秒表来衡量一个动作运行所需的时间。 动作完成后,我会根据时间做逻辑。更具体地说,我检查时间是否超过了某个阈值。

我最近发现了Task.Wait(int timeout)方法

将我的操作放在任务中并在阈值上等待是否更好?

例如:

bool isOnTime=false;
Task action = new Task(() => someMethod());
action.Start();
isOnTime = action.Wait(myThreshold);

if(!isOnTime)
{
...some code
}

编辑:更新问题,因为每个人都认为我想要运行任务

这就是我目前的做法:

Stopwatch watch = Stopwatch.StartNew();
someMethod();
watch.Stop();
executeTime = watch.ElapsedMilliseconds;

以后我正在跑步:

if (executeTime > Threshold)

我正在同步运行该方法,我希望保持这种方式

4 个答案:

答案 0 :(得分:1)

现在发生的情况是,如果操作的时间超过myThreshold,则操作将被取消。我不认为这就是你想要的。除此之外,您还使用.Wait()阻止调用线程。

我会说坚持使用秒表或者想别的东西。

编辑:我的不好,我对Task.Wait()的理解不正确。我今天学到了一些东西,所以这很好: - )

但是,除非someMethod是异步方法,否则您正在使用另一个线程。因此,如果并发不是问题,那将是一个不错的选择。

答案 1 :(得分:1)

  

如果动作的持续时间超过我的阈值

,则可以

看起来你想异步运行它,然后Task.Wait更合适,因为你会尽快获得有关超时的信息(而方法可能仍会运行更长时间)。

您可以使用包装器方法运行类似于

bool IsCompletedInTime(Action action, int msTimeout) =>
    Task.Run(() => action()).Wait(msTimeout);

用法:

if(!IsCompletedInTime(someMethod, myThreshold))
{
    ... // timeout
}

答案 2 :(得分:1)

这是一种合理的方法。您可以在超时后放弃任务。

问题在于,任务可能会在超时后消耗资源或导致副作用。实施取消方案并取消任务通常会更好:

var cts = new CTS();
var task = Task.Run(() => F(cts.Token));
cts.CancelAfter(...);
task.Wait();

在这里,我们总是等待任务以确保它被关闭。 F有责任确保及时取消。

这样我们就可以避免因可能的流氓任务而导致的所有并发问题。

答案 3 :(得分:0)

也许你应该通过使用延续来处理完成任务所需的时间来避免阻塞。

例如:

using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace Demo
{
    class Program
    {
        static void Main()
        {
            Stopwatch sw = new Stopwatch();

            var task = new Task(() => 
            {
                sw.Start();
                someMethod();
            });

            task.Start();

            task.ContinueWith(antecedent => 
            {
                if (sw.ElapsedMilliseconds >= 1000 )
                    Console.WriteLine("Took at least second.");
                else
                    Console.WriteLine("Took less than a second.");
            });

            Console.WriteLine("Press <ENTER> to exit.");
            Console.ReadLine();
        }

        static void someMethod()
        {
            Thread.Sleep(2000);
        }
    }
}

然后在等待任务完成时你不会阻止任何任务。