我有一个简单的应用程序,它连接到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
}
答案 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;事件强>
处理此案例的另一种方法是使用Timers
和Evenets
。您将设置计时器,它将在您每次需要时完成工作。一旦找到结果,它就会向您发送消息。 这是正确的方法,但将Thread
放到Sleep
也可以。
选中Comparing Timer with DispatcherTimer以选择要使用的定时器。
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秒超时。