1

Silverlightの非同期要件は、実際には複雑なコードになります。Silverlight 4の問題アクションコールバックを使用してファイルアップロードが成功したかどうかを確認するとき

私はちょうどthis answerのようなファイルをアップロードしています。

違いは、ファイルをMVCアクションメソッドに投稿することです。すべてのファイルは、その答えの一番下にコメントしたように、ファイルが正常にアップロードされていないときにコールバックを取得しません。

私はmvcアプリケーション(Services/CheckForFile/{id})に別のアクションメソッドを作成し、ファイルが見つかったかどうかによって文字列を返します。

今、どのように、私は呼んでないとき、このMVCアクションメソッドが問題である: BeginCheck()関数を実行すると、ファイル、何らかの理由で、NEVERアップロード:ここ

void DoUpload() { //Gets call on BtnUpload.Click 
       //opn is an OpenFileDialog 
      up.UploadFile(_filename, opn.File.OpenRead(), 
       e => 
       { 
       //do some ui stuff here. 
        BeginCheck();// calling this causes PROBLEMS! 
       }); 
    } 
    private void BeginCheck() 
    { 
     Uploader up = new Uploader(); 
     up.CheckForFile(_filename, success => 
     { 
      if (!success) 
      { 
       MessageBox.Show("There was problem uploading the file. Please try again", "Error", MessageBoxButton.OK); 
      } 
     }); 
    } 

が問題です!私がそれをコメントアウトすれば! BeginCheck()はアップロード中に実行されるようですか?の後にを実行してはいけません!

どのように/どこで、ファイルがアップロードされていることを確認するために、アップロード後BeginCheck()を呼び出すのでしょうか?ここで

私はアップローダクラスを定義した方法です:

public class Uploader 
    { 
     public void UploadFile(string fileName, Stream data, Action<Exception> callback) 
     { 
      UriBuilder ub = new UriBuilder(_mvcurl+"Services/UploadFile/" + fileName); 
      WebClient c = new WebClient(); 
      c.OpenWriteCompleted += (sender, e) => 
      { 
       try 
       { 
        PushData(data, e.Result); 
        e.Result.Close(); 
        data.Close(); //this does not block. 
        callback(null);//this ALWAYS hits! 
       } 
       catch (Exception err) 
       { 
        if (callback != null) 
        { 
         callback(err); 
        } 
       } 
      }; 
      c.OpenWriteAsync(ub.Uri); 
     } 
     public void CheckForFile(string filename, Action<bool> callback) 
     { 
      UriBuilder ub = new UriBuilder(_mvcurl+"Services/CheckForFile/" + fileName); 
      WebClient c = new WebClient(); 
      c.OpenReadCompleted += (sender, e) => 
       { 
        using (StreamReader sw = new StreamReader(e.Result)) 
        { 
         if (sw.ReadToEnd().Equals("Found", StringComparison.InvariantCultureIgnoreCase)) 
         { 
          callback(true); 
         } 
         else 
         { 
          callback(false); 
         } 
        } 
       }; 
      c.OpenReadAsync(ub.Uri); 
     } 
     private void PushData(Stream input, Stream output) 
     {//4KB is not a limitation. We only copy 4Kb at a time from in to out stream 
      byte[] buffer = new byte[4096]; 
      int bytesRead; 
      while ((bytesRead = input.Read(buffer, 0, buffer.Length)) != 0) 
      { 
       output.Write(buffer, 0, bytesRead); 
      } 
     } 
    } 

答えて

1

私はあなたが参照する私のオリジナルの答えは完全に正確ではないことを言ってembarrasedです。それはOPが望んでいたもののために働くように思われますが、実際にコードは私がそれを思った時点でブロックしません。実際にあなたが実際に探しているのはWriteStreamClosedイベントです。ここではリクエストの失敗を検出できます。サーバーは、ファイルのアップロードに応答した後

 public void UploadFile(string fileName, Stream data, Action<Exception> callback) 
     { 
      UriBuilder ub = new UriBuilder(_mvcurl+"Services/UploadFile/" + fileName); 
      WebClient c = new WebClient(); 
      c.OpenWriteCompleted += (sender, e) => 
      { 
       try 
       { 
        PushData(data, e.Result); 
        e.Result.Close(); 
        data.Close(); //this does not block. 
       } 
       catch (Exception err) 
       { 
        if (callback != null) 
         callback(err); 
       } 
      }; 
      c.WriteStreamClosed += (sender, e) => 
      { 
       if (callback != null) 
        callback(e.Error); 
      } 
      c.OpenWriteAsync(ub.Uri); 
     } 

今、あなたのBeginCheckのみ実行されます - :ここで

は、あなたが期待しているように動作しますammendedバージョンです。

+0

+1ありがとうございます!しかし、私は 'BeginCheck()'が必要でしょうか?私は、何かがうまくいかない場合、私は例外の権利を得るのですか? – gideon

+0

@Giddy:BeginCheckの唯一の目的は、私の古いコードが実際に動作していなかったという事実を回避することだったなら、あなたは正しいです。BeginCheckはまったく必要ありません。 – AnthonyWJones

+0

素晴らしい!ありがとうございました! =) – gideon

関連する問題