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ありがとうございます!しかし、私は 'BeginCheck()'が必要でしょうか?私は、何かがうまくいかない場合、私は例外の権利を得るのですか? – gideon
@Giddy:BeginCheckの唯一の目的は、私の古いコードが実際に動作していなかったという事実を回避することだったなら、あなたは正しいです。BeginCheckはまったく必要ありません。 – AnthonyWJones
素晴らしい!ありがとうございました! =) – gideon