2011-04-04 19 views
4

私の銀色のアプリではファイルアップロードを行います。私はファイルを塊に分割してから、それぞれの塊をアップロードします。問題は、HttpWebRequestを同期的に使用したいということです。私の約束は、すべての要求が正常であり、例外を捕捉することです。 Silverlightでも可能ですか?あなたが私に私はこれを取得する方法のヒントを与えることができSilverlight HttpWebRequest同期コール

while(chunk) 
{ 
    try{ 
    HttpWebRequest req = ... 
    req.BeginGetRequestStream(new AsyncCallback(WriteCallback), req); 
    //add data into request stream 
    req.BeginGetResponseStream(new AsyncCallback(ReadCallback), req); 
    //parse the response 
    chunk = new Chunk(); 
    }catch(Exception ex) 
    {...} 
} 

:私は次のようにsopmething希望ですか?

おかげで、 ラドゥD

答えて

2

Silverlightは同期Web要求をサポートしていません。このため、私はSimple Asynchronous Operation Runnerと書いた。その目的の1つは、コードが同期しているかのようにコードを記述し、ランナーコードで動作するように変更できることです。

まず、パート1からAsyncOperationServiceの小さなコードを取得してプロジェクトに追加します(実際に使用するのに重要でない記事が少し重いと気にしないでください)。すでに「同期テンプレート」として提供されたコードを使用して

我々は、同様のプロジェクトに追加しますので、我々はそれらを記述しますGetRequestStreamGetResponseStreamためAsyncOperation実装のカップルを必要と見ることができます: -

public static class WebRequestAsyncOps 
{ 
    public static AsyncOperation GetRequestStreamOp(this WebRequest request, Action<Stream> returnResult) 
    { 
     return (completed) => 
     { 
      request.BeginGetRequestStream((result) => 
      { 
       try 
       { 
        returnResult(request.EndGetRequestStream(result)); 
        completed(null); 
       } 
       catch (Exception err) 
       { 
        completed(err); 
       } 
      }, null); 
     }; 
    } 

    public static AsyncOperation GetResponseOp(this WebRequest request, Action<WebResponse> returnResult) 
    { 
     return (completed) => 
     { 
      request.BeginGetResponse((result) => 
      { 
       try 
       { 
        returnResult(request.EndGetResponse(result)); 
        completed(null); 
       } 
       catch (Exception err) 
       { 
        completed(err); 
       } 
      }, null); 
     }; 
    } 
} 

今、あなたはおそらく、私はあなたが(既存AsyncOperationServiceクラスに注入する)だけでなく、手でこのAsyncOperationを持ってお勧めしますので、UIに進捗状況を報告したいと思うアップロードファイルをチャンクしている場合: -

public static AsyncOperation SwitchToUIThread() 
    { 
     return (completed => Deployment.Current.Dispatcher.BeginInvoke(() => completed(null))); 
    } 

今、私たちはあなたのコードの非同期バージョンクレアーレすることができます -

IEnumerable<AsyncOperation> Chunker(Action<double> reportProgress) 
{ 
    double progress = 0.0; 
    Chunk chunk = new Chunk(); 
    // Setup first chunk; 
    while (chunk != null) 
    { 
      Stream outStream = null; 
      HttpWebRequest req = ... 

      yield return req.GetRequestStreamOp(s => outStream = s); 

      // Do stuff to and then close outStream 
      WebResponse response = null; 

      yield return req.GetResponseOp(r => response = r); 

      // Do stuff with response throw error is need be. 
      // Increment progress value as necessary. 

      yield return AsyncOperationService.SwitchToUIThread(); 

      reportProgress(progress); 

      chunk = null; 
      if (moreNeeded) 
      { 
      chunk = new Chunk(); 
      // Set up next chunk; 
      } 
     } 
} 

最後に、あなたはそれを実行し、すべてのエラーを処理する必要があります -

Chunker.Run((err) => 
{ 
    if (err == null) 
    { 
      // We're done 
    } 
    else 
    { 
      // Oops something bad happened. 
    } 

}); 
1

同期機能を実行することにより、メインUIスレッドをブロックするために絶対に大丈夫ではないです。

大規模なファイルを非同期メカニズムを使用してチャンクにアップロードすることはできます。 WCFサービスをご利用の場合は、this postをご確認ください。 JAXWS上で動作するSOAP Webサービスを使用して同じことを行ったので、あなたのバックエンドとは何の関係もありません。

関連する問題