2009-08-06 16 views

答えて

0

指定された時間が経過した後で、Timerオブジェクト(GCSafeTimerオブジェクトがわからない場合は、そのオブジェクトをGoogleを使用します)を使用して、中止する独自の機能を記述しない限り、

1

私はそれを行うための組み込みの方法はありません。 しかし、自分で実装することは間違いありません。

NetConnectionインスタンスに対して行う各呼び出しを表すトランザクションクラスを作成するだけです。

"NetTransaction"などのこのトランザクションクラスでは、すべてのアクティブなトランザクションのプライベート静的リストを保持する必要があります。結果ハンドラ関数は、トランザクションが完了すると呼び出されるプライベートインスタンス変数に格納する必要がありますオン状態、またはタイムアウト時)。このハンドラは統一されているので、すべての種類の結果(成功/エラー/タイムアウト/キャンセル)を処理します。

トランザクションクラスのコンストラクタで、 "この"新しいインスタンスをアクティブなトランザクションリストに追加し、非ゼロタイムアウトが指定されている場合はタイムアウトタイマーを開始し(次に説明するcancelTransaction関数をポイントするイベントリスナーを追加)、最後にネットワークコールを実行します。

トランザクション(成功/エラー/タイムアウト/キャンセル)を完了したら、アクティブなトランザクションリストからトランザクションを削除し、タイムアウトタイマーが設定されていればそれを取り消し、最後に意味のある結果を結果ハンドラ関数に転送します。

これをすべて行うには、トランザクションクラスで結果ハンドラ関数とステータスハンドラ関数を作成し、NetConnectionへの呼び出しにTHOSEを渡す必要があります。これらの2つの関数は、ネットワーク結果(結果またはステータス)のインターセプト、トランザクションの完了(前述)、およびコンストラクタに渡されたREAL結果ハンドラ関数への統一結果の転送を行います。

ここでは基本的な必要性を持つ基本NetTransactionクラスの内部を取り上げます。私の実装には、トランザクションIDの生成(単純な静的カウンタ、ID番号でアクティブなトランザクションを検索するメソッド、トランザクションのデータオブジェクトのオーバーライド可能なget/setメソッドがあるため、自動ヘッダーラッピング/ NetTransaction(例えばWidgetNetTransaction)から派生するクラスでカスタムデータプロトコルにアンラップ。

static private var active_transactions:Array = new Array(); //active network requests pending a result 
static private var transaction_count:int = 0; //incremented each time a NetTransaction instance is created so each one can have a unique transaction id number assigned to it 

private var transaction_id:int; //Transaction identifier, which may assist a widget in managing its own concurrent transactions. It comes from a static field, auto-incremented in the NetTransaction constructor, so it is always unique for each NetTransaction within the current session... unless more than 2147483648 transactions occur in a single session and the value wraps around, but by then, old transactions wil be forgotten and there shouldn't be any problems as a result. 
private var description:String; //an optional description string to describe the transaction or what it is supposed to do (especially for error-reporting purposes). 
private var request_data:Object; //this stores the data that will be forwarded to your web server 
private var result_handler:Function; //this is the method to be called after intercepting a result or status event. it's left public, because it's acceptable to modifiy it mid-transaction, although I can't think of a good reason to ever do so 
private var internal_responder:Responder; //internal responder attached to the transaction 
private var timeout:int; 
private var timeout_timer:Timer; 

//Constructor 
public function NetTransaction(network_service:NetworkService, request_data:Object, result_handler:Function = null, description:String = null, timeout:int = 0) 
{ 
    //Throw something a little more friendly than a null-reference error. 
    if (network_service == null) 
     throw new ArgumentError("A NetworkService object must be specified for all NetTransaction objects."); 
    if (timeout < 0) 
     throw new ArgumentError("Timeout must be 0 (infinite) or greater to specify the number of milliseconds after which the transaction should be cancelled.\rBe sure to give the transaction enough time to complete normally."); 

    //Save information related to the transaction 
    this.result_handler = result_handler; 
    this.request_data = request_data; 
    this.internal_responder = new Responder(net_result, net_status); //should use override versions of these methods 
    this.description = description; 
    this.timeout = timeout; 
    this.timeout_timer = null; 

    //Grab a new transaction id, add the transaction to the list of active transactions, set up a timeout timer, and finally call the service method. 
    this.transaction_id = transaction_count++; 
    active_transactions.push(this); //transaction is now registered; this is done BEFORE setting the timeout, and before actually sending it out on the network 
    if (timeout > 0) //zero, represents an infinite timeout, so we'll only create and start a timer if there is a non-zero timeout specified 
    { 
     timeout_timer = new Timer(timeout, 1); 
     timeout_timer.addEventListener(TimerEvent.TIMER, this.cancelTransaction, false, 0, true); 
     timeout_timer.start(); 
    } 
    network_service.call(internal_responder, request_data); 
} 


//Finalizes a transaction by removing it from the active transactions list, and returns true. 
//Returns false to indicate that the transaction was already complete, and was not found in the active transactions list. 
private function completeTransaction():Boolean 
{ 
    var index:int = active_transactions.indexOf(this); 
    if (index > -1) 
    { 
     active_transactions.splice(index, 1); 
     if (timeout_timer != null) 
     { 
      timeout_timer.stop(); 
      timeout_timer.removeEventListener(TimerEvent.TIMER, this.cancelTransaction, false); 
     } 
     return true; 
    } 
    else 
    { 
     //Transaction being removed was already completed or was cancelled 
     return false; 
    } 
} 

//An instance version of the static NetTransaction.cancelTransaction function, which automatically passes the transaction instance. 
public function cancelTransaction(details_status_object:Object = null) 
{ 
    NetTransaction.cancelTransaction(this, details_status_object); 
} 

//Cancels all active transactions immediately, forcing all pending transactions to complete immediately with a "NetTransaction.Call.Cancelled" status code. 
static public function cancelAllActiveTransactions(details_status_object:Object) 
{ 
    for each (var transaction:NetTransaction in active_transactions) 
     transaction.cancelTransaction(details_status_object); 
} 

//Cancels the transaction by spoofing an error result object to the net_status callback. 
static public function cancelTransaction(transaction:NetTransaction, details_status_object:Object) 
{ 
    //Build cancel event status object, containing somewhat standard properties [code,level,description,details,type]. 
    var status:NetTransactionResultStatus = new NetTransactionResultStatus(
     "NetTransaction.Call.Cancelled", 
     "error", //cancelling a transaction makes it incomplete, so the status level should be "error" 
     "A network transaction was cancelled. The description given for the transaction was: " + transaction.description, 
     details_status_object, //include, in the details, the status object passed to this method 
     "" //no type specified 
    ); 
    //Call the net_status handler directly, passing a dynamic Object-typed version of the NetTransactionResultStatus to the net_status handler. 
    transaction.net_status(status.ToObject()); 
} 

//Result responder. Override, then call when you're ready to respond to pre-process the object returned to the result_handler. 
protected function net_result(result_object:Object):void 
{ 
    if (completeTransaction()) 
     if (result_handler != null) 
      result_handler.call(null, new NetTransactionResult(this, result_object, null)); 
} 

//Status responder. Override, then call when you're ready to respond to pre-process the object returned to the result_handler. 
protected function net_status(status_object:Object):void 
{ 
    if (completeTransaction()) 
     if (result_handler != null) 
      result_handler.call(null, new NetTransactionResult(this, null, NetTransactionResultStatus.FromObject(status_object))); 
} 

NetTransactionResultとNetTransactionResultStatusクラスは、私は、統一の結果に送信するタイプセーフな結果のために設定しただけのシンプルなデータクラスですNetTransactionResultにnull以外のステータスプロパティがある場合は結果をエラーとして解釈し、そうでない場合は結果を成功として解釈し、含まれているデータを使用します。NetworkServiceクラスは単なるラッパーです。呼び出しパスの指定を処理するNetConnectionクラスをラウンドし、すべての低レベルNetConnectionエラーイベントを処理し、NetTransactionクラスと互換性のあるステータスメッセージをパッケージ化し、最後にcancelAllTransactionsを呼び出します。

タイムアウトを含むどのような種類のエラーが発生しても、トランザクションの結果ハンドラが常に呼び出され、結果を処理するために必要なすべての情報(成功/エラー/タイムアウト/キャンセル)。これにより、NetConnectionオブジェクトをローカル関数を呼び出すのと同じくらい簡単で信頼性の高いものにすることができます。

関連する問題