计时器结束后返回值

时间:2016-11-28 11:31:43

标签: c# timer

我有一个简单的应用程序,它连接到API,扫描文件并检查其状态。扫描可能需要一段时间,我想问一下#39;关于文件状态每隔5秒api,如果它是干净的 - 返回true,如果是其他 - 返回false。 问题是我不知道如何告诉程序在返回值之前等待条件。我的代码看起来像这样:

bool Scan(string filePath){
    Scanner.Scan(filePath);
    //now repeat line below every 2s until the result is positive
    var result = Scanner.CheckStatus();
    // I dont want to go below before status is positive or x seconds has elapsed
    return result
}

3 个答案:

答案 0 :(得分:2)

<强>线程

下面的例子将放下你的线程。这意味着如果您的应用程序是单线程的,那么在此期间您将无法执行任何其他操作。

休眠线程的代码是:

System.Threading.Thread.Sleep(1000); //time in ms, 1 sec

@EpicSam的评论:这将使您的程序在睡眠期间无响应。如果您有某种需要响应的用户界面,请考虑使用以下代码:

await Task.Delay(5000);

在示例中,它应该如下所示:

bool Scan(string filePath){
    Scanner.Scan(filePath);
    var result = Scanner.CheckStatus();
    while(result != ResultType.Positive)
    {
        System.Threading.Thread.Sleep(5000); //time in ms
        result = Scanner.CheckStatus();
    }
    return result
}

简化为:

bool Scan(string filePath){
    Scanner.Scan(filePath);
    ResultType result;

    while((result = Scanner.CheckStatus()) != ResultType.Positive)
        System.Threading.Thread.Sleep(5000); //time in ms

    return result
}

计时器&amp;事件

处理此案例的另一种方法是使用TimersEvenets。您将设置计时器,它将在您每次需要时完成工作。一旦找到结果,它就会向您发送消息。 这是正确的方法,但将Thread放到Sleep也可以。

选中Comparing Timer with DispatcherTimer以选择要使用的定时器。

  • 请注意,下面的代码会为Threads制作不同的结果 - &gt;它确实在循环中运行整个Scan方法。其中包括运行Scanner.Scan()方法

-

using System.Timers;

public class MyClass
{
    Timer mTimer;
    string mFilePath;

    public delegate void StatusCheck(bool value);
    public event StatusCheck StatusChecked; 

    MyClass(string filePath)
    {
        mFilePath = filePath;

        mTimer = new Timer(); //time in ms
        mTimer.Elapsed += new ElapsedEventHandler(Scan);
    }

    public void Start()
    { mTimer.Enabled=true; }

    private void Scan(object source, ElapsedEventArgs e)    
    {
        Scanner.Scan(filePath);
        ResultType result;
        if(result = Scanner.CheckStatus())
        {
            this.StatusChecked?.Invoke(result); 
        }
    }

}

用法如下:

//some code ...
MyClass checker = new MyClass("C:\a.txt");
checker.StatusChecked += new StatusCheck(myVoid);
checker.Start();

//some more code ..

private void myVoid(bool result)
{
    Console.WriteLine("My result is: " + result );
}

答案 1 :(得分:1)

async/await方法看起来很清楚。即使您没有UI,也可以使用async/await

async Task<bool> Scan(string filePath)
{
    Scanner.Scan(filePath);
    var result = Scanner.CheckStatus();

    while(result == false)
    {
        await Task.Delay(2000);
        result = Scanner.CheckStatus();
    }

    return result
}

因为你的Scanner.Scan方法使用了IO - 它变得非常适合使用async/await的异步方法。

答案 2 :(得分:0)

bool Scan(string filePath)
{
    var timeout = new TimeSpan(0,0,5);
    Scanner.Scan(filePath);
    Stopwatch stopwatch = Stopwatch.StartNew();

    do 
    {
        result = Scanner.CheckStatus();
        if(result) return true;

        System.Threading.Thread.Sleep(2000);

    } while(stopwatch.Elapsed < timeout)

    return false;
}

请注意,这是一个简单但天真的实现,因为它不会阻止CheckStatus()调用本身超过5秒超时。