[英]What is the best way to delay a console application for a few seconds
概述。
我有一个用C#.NET 4.0编写的Windows服务,该服务与Betfair API挂钩,可以自动进行投注(所有投注决定均在SQL DB中完成)。 该服务具有多个计时器,这些计时器为3个主要区域设置了一些轮询(下注待决,查看价格,在比赛中下注)。 计时器全部每30秒触发一次。
我遇到的困难是InPlay投注之一。 计时器每30秒一次调用我的BetfairBot对象中的方法,该方法检查即将进行的比赛并为其下注。 在同一场比赛上可能有多个系统下注,因此我想在parrallel中启动“控制”方法,因此一个系统在下注之前不会等待另一个系统完成。
所以我有一些像这样的代码来触发并行控制方法
// some SQL to get my upcoming races
DataTable sqlRecordset = this.dataAccess.GetDataTable(SQL);
try
{
// run in parallel for each system and concurrent races
Parallel.ForEach(sqlRecordset.AsEnumerable(), recordsetRow =>
{
betfairLogon = recordsetRow["BetfairLogon"].ToString();
betfairPassword = recordsetRow["BetfairPassword"].ToString();
SystemPK = Convert.ToInt32(recordsetRow["SystemPK"]);
systemName = recordsetRow["SystemName"].ToString();
RacePK = Convert.ToInt32(recordsetRow["RaceFK"]);
// spawn thread for each system
this.RunInPlayBettingControl(SystemPK, betfairLogon, betfairPassword, systemName, RacePK);
});
}
catch (Exception e)
{
// log error
HelperLib.LogMsg("Error starting Parallel Threads for RacePK: " + RacePK.ToString() + " - " +e.Message.ToString());
}
然后,在我的控制方法中,我循环执行直到下注结束,然后调用另一个处理下注的方法,并返回结果代码,告知我的系统下注的状态,例如,比赛是否结束,尚未开始或即将开始。
在这些状态中,我想在重新调用下注方法之前将线程延迟几秒钟。
我努力了
Thread.Sleep(2500);
但这根本就不等待,投注过程无需等待就立即被再次调用。
我已经阅读了一些有关线程的知识,但不知道问题出在我的并行循环中,该循环触发对我的控制方法的并行调用(需要按需延迟线程),还是我的控制方法和Thread.Sleep (延迟)通话。
我位于Service类中的初始计时器运行良好,我不知道解决此问题的最佳方法,也不知道延迟存在什么问题,因为我认为由并行循环启动的每个线程都将独立运行,因此如果需要,延迟一个.Sleep调用。
我应该使用更多的计时器还是其他方法?现有的循环代码最好的方法是什么?
并行循环触发的Control方法如下。 实际投注方法的代码过于复杂,无法在此处发布,但是它没有线程调用,而只是一些SQL和一些对Betfair API的调用。
任何帮助将非常感激。 提前致谢。
public void RunInPlayBettingControl(int SystemPK,string betfairLogon, string betfairPassword, string systemName, int RacePK)
{
int result = 0;
bool quit = false; // we loop until true
// decode our encrypted logon details
betfairPassword = HelperLib.GetPassword(betfairLogon);
betfairLogon = HelperLib.DecodeLogon(betfairLogon);
// create API object
this.betfairAPI = new BetfairAPI(systemName);
// try and log in for this system and save the session for future use
if (!String.IsNullOrEmpty(betfairLogon) && !String.IsNullOrEmpty(betfairPassword))
{
// check logged in status as we might have used previous session otherwise log in now
if (!this.betfairAPI.IsLoggedIn() && this.betfairAPI.Login(betfairLogon, betfairPassword) == false)
{
// couldnt login so exit
return;
}
else
{
// save session to file
this.betfairAPI.SaveSession(systemName);
// we loop until we know there is no more point in doing so
while (!quit)
{
// result code values
// 0 = We have no idea whats going on yet
// 1 = Race is actually closed/finished so exit
// 2 = Race is inplay but we are not ready to bet yet - wait a short while
// 3 = Race is inplay and ready to bet
// 4 = Race is not inplay yet so wait a bit and carry on
// this is our main betting method that handles all our betting
result = this.RunInPlayBetting(SystemPK, betfairLogon, betfairPassword, systemName, RacePK);
// check result to see if we quit looping
switch (result)
{
case 1:
// race is over so exit
quit = true;
break;
case 2:
// race is in play but not over our marker yet so go back in after a short wait
Thread.Sleep(1000); // NOT WORKING
quit = false;
break;
case 3:
// race is in play so lets go straight back in and try some more betting
quit = false;
break;
case 4:
// not in play yet so keep looping after a short wait
quit = false;
Thread.Sleep(2500); // NOT WORKING
break;
case 0:
// have no idea whats going just quit loop
quit = true;
break;
}
}
}
}
return;
}
Thread.sleep代码(2500);
但这根本就不等待,投注过程无需等待就立即被再次调用。
Thread.Sleep()
将在指定时间内挂起当前线程。 您看到的是其他线程执行相同的方法(我假设您那里有一个断点用于检查),因为您使用Parallel.ForEach()
生成了一堆。
我不太确定你要干什么。 您是否希望能够暂时停止对RunInPlayBettingControl方法的所有新调用? 如果是,则必须执行线程同步。 那样做:
class XYZ
{
Object syncObj = new Object();
...
public void RunInPlayBettingControl(int SystemPK,string betfairLogon, string betfairPassword, string systemName, int RacePK)
{
lock(this.syncObj)
{ }
...
switch(...)
{
...
case 2:
// race is in play but not over our marker yet so go back in after a short wait
lock(this.syncObj)
{
Thread.Sleep(1000);
}
...
}
}
}
这样,您将保留对RunInPlayBettingControl的任何新调用,但运行中的调用将结束。
这有帮助吗?
通常,尽管您应避免调用Thread.Sleep,因为在此期间线程处于锁定等待状态,这将阻止应用程序退出(除非它是后台线程)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.