2016-10-10 30 views
1

タクシー(これはゲームアプリケーションです)に電話をかけることができるシステムがあり、このタクシーには10秒かかります。問題は です。私もcanceltaxi関数を持っていて、System.Threading.Timerを停止する方法を知る必要があります。なぜなら、タクシーを注文すると、キャンセルした後です。 別のタクシーを注文した後、それはまだ古いタクシータイマー、 を使用しているので、10に来るのに2秒かかりますそれを停止するには?System.Threading.Timerを停止する方法

私はこのコードを試しましたが、それでも停止しません。私はそれを取り消したいときにこのvoidと呼んでいます。

public void StopTaxiTimer() 
     { 
      taxiTimerInstance.Dispose(); 
      taxiTimerInstance = null; 
      this.Dispose(); 
     } 

全クラス:CallTaxiオン

using log4net; 
using Plus.Communication.Packets.Outgoing.Rooms.Chat; 
using Plus.HabboHotel.GameClients; 
using Plus.HabboHotel.Roleplay.Instance; 
using Plus.HabboHotel.Rooms; 
using System; 
using System.Threading; 

namespace Plus.HabboHotel.Roleplay.Timers 
{ 
    public sealed class TaxiTimer : IDisposable 
    { 
     private static readonly ILog myLogger = LogManager.GetLogger("Plus.HabboHotel.Roleplay.Timers.DeathTimer"); 

     private Timer taxiTimerInstance; 
     private uint timerTimeSeconds; 
     private RoleplayInstance roleplayInstance; 

     public TaxiTimer(RoleplayInstance roleplayInstance) 
     { 
      Console.WriteLine("Setup TaxiTimer for " + roleplayInstance.GetSession().GetHabbo().Username + " (" + roleplayInstance.TaxiWaitTimeSeconds + " seconds)"); 
      this.timerTimeSeconds = roleplayInstance.TaxiWaitTimeSeconds; 
      this.roleplayInstance = roleplayInstance; 
      this.taxiTimerInstance = new Timer(new TimerCallback(this.OnTimerElapsed), null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)); 
     } 

     public void OnTimerElapsed(object Obj) 
     { 
      try 
      { 
       if (taxiTimerInstance == null) 
        return; 

       if (roleplayInstance == null || !roleplayInstance.CalledTaxi || roleplayInstance.GetSession() == null || roleplayInstance.GetSession().GetHabbo() == null) 
        return; 

       GameClient gameSession = roleplayInstance.GetSession(); 

       if (roleplayInstance.TaxiWaitTimeSeconds < 1) 
       { 
        Room currentRoom = gameSession.GetHabbo().CurrentRoom; 
        if (currentRoom == null) 
         return; 

        RoomUser roomUser = currentRoom.GetRoomUserManager().GetRoomUserByHabbo(gameSession.GetHabbo().Id); 
        if (roomUser == null) 
         return; 

        roleplayInstance.CalledTaxi = false; 
        currentRoom.SendMessage(new ShoutComposer(roomUser.VirtualId, "*Gets transported to my destination*", 0, roomUser.LastBubble)); 
        gameSession.GetHabbo().PrepareRoom(roleplayInstance.TaxiRoomId, string.Empty); 
       } 
       else 
       { 
        roleplayInstance.TaxiWaitTimeSeconds--; 
       } 
      } 
      catch (Exception ex) 
      { 
       myLogger.Error(ex.Message); 
       myLogger.Error(ex.StackTrace); 
      } 
     } 

     public void StopTaxiTimer() 
     { 
      taxiTimerInstance.Dispose(); 
      taxiTimerInstance = null; 
      this.Dispose(); 
     } 

     public void Dispose() 
     { 
      GC.SuppressFinalize(this); 
     } 
    } 
} 

roleplayInstance.TaxiWaitTimeSeconds = Convert.ToUInt32(PlusEnvironment.GetRPManager().GetSettings().GetSettingValueByKey("roleplay_taxi_wait_seconds")); 
        roleplayInstance.TaxiRoomId = goingTo.RoomId; 
        roleplayInstance.TaxiTimer = new HabboHotel.Roleplay.Timers.TaxiTimer(roleplayInstance); 
+0

は 'taxiTimerInstance.Change(Timeout.Infinite、Timeout.Infinite)を試してみてください;'あなたは、次の順序に戻って10秒にそれをリセットする必要があります。 https://msdn.microsoft.com/en-us/library/yz1c7148(v=vs.110).aspx – TyCobb

答えて

4

、そのタクシー:これを試してみてくださいそれはまだ古いタクシーのタイマーを使用しているので、10秒で来るのに2秒かかる、どうすればそれを停止するのですか?

あなたが決してタイマーを作っていなければ、タイマーをキャンセルすることについて心配する必要はありません。

キャンセルを伴う非同期ワークフローについて説明しています。 C#と.NETフレームワークにはすでにこの機能があるので、独自の機能を使用するよりもむしろ使用してください。

awaitTask.DelayタスクのワークフローがCancellationTokenasyncワークフローメソッドを作成します。遅延の継続はタクシーの到着です。取り消しメソッドは、トークンを取り消すことによってタスクを失敗させます。

このメカニズムには多くの文書があるので、それを読んでください。開始するには良い場所はここにある:

https://msdn.microsoft.com/en-us/library/dd997364

1

あなたのコードで起こって嫌なものの多くがあるようです。私が見るいくつかの警告兆候があります。

IDisposableを正しく実装していません。

public class ExampleDisposable : IDisposable 
{ 
    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      // free managed resources 
     } 
     // free native resources if there are any. 
    } 
} 

また、イベントハンドラの名前付け規則を使用しました。イベントを発生させる方法は通常On*と呼ばれ、それらのイベントを処理する方法は*です。したがって、あなたの場合、public void OnTimerElapsed(object Obj)の代わりに、それは慣例によりpublic void TimerElapsed(object Obj)でなければなりません。

また、catch (Exception ex)で例外をキャッチしています。それはちょうど悪い反パターンです。 Eric Lippert's Vexing Exceptionsを読んでください。

最後に、私はこの種のクラスをとにかく避けることを提案します。代わりにMicrosoftのリアクティブフレームワークを使用してください(NuGet "System.Reactive")。あなたはあなただけrequestTaxi.OnNext(roleplayInstance);を書くタクシーを呼びたいとき今

Subject<RoleplayInstance> requestTaxi = new Subject<RoleplayInstance>(); 

IDisposable subscription = 
    requestTaxi 
     .Select(ri => 
      ri == null 
      ? Observable.Never<RoleplayInstance>() 
      : Observable 
       .Timer(TimeSpan.FromSeconds((double)ri.TaxiWaitTimeSeconds)) 
       .Select(n => ri)) 
     .Switch() 
     .Subscribe(ri => 
     { 
      GameClient gameSession = ri.GetSession(); 
      Room currentRoom = gameSession.GetHabbo().CurrentRoom; 
      RoomUser roomUser = currentRoom.GetRoomUserManager().GetRoomUserByHabbo(gameSession.GetHabbo().Id); 
      currentRoom.SendMessage(new ShoutComposer(roomUser.VirtualId, "*Gets transported to my destination*", 0, roomUser.LastBubble)); 
      gameSession.GetHabbo().PrepareRoom(roleplayInstance.TaxiRoomId, string.Empty); 
     }); 

その後、あなたはこれを書くことができます。タクシーが呼び出される前にもう一度呼び出すと、自動的にイベントが再開されます。 requestTaxi.OnNext(null);で呼び出すと、現在の要求はすべてキャンセルされますが、後で新しい要求を処理する準備ができています。

完全にシャットダウンする場合は、subscription.Dispose();に電話してください。すべて私は思っています。

0

Timer.Changeメソッドのツールチップを読みましたか?その後、彼らは別のタクシーを注文ストレートの後、彼らはタクシーを注文する場合、キャンセルので、私はそれが後の8秒を言うことができます私はSystem.Threading.Timerを停止することができます方法を知っておく必要があり

timer.Change(Timeout.Infinite, Timeout.Infinite); 
関連する問題