簡體   English   中英

延遲控制台應用程序幾秒鍾的最佳方法是什么

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM