Таким образом, асинхронное требование для silverlight заканчивается каким-то действительно запутанным кодом !!
Я загружаю файл точно так же, как этот ответ предлагает.
Разница в том, что я отправляю файл в метод действия MVC.Все работает с файлом, за исключением того, что, как я прокомментировал в нижней части этого ответа, я не получаю никакого обратного вызова, когда файл НЕ успешно загружен.
Итак, я создал другой метод действия в своем приложении mvc (Services/CheckForFile/{id}
), и он возвращает строку в зависимости от того, найден ли файл.
Теперь, как и когда я вызываю этот mvcПроблема в методе действия:
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 () работает во время загрузки или что-то?Разве он не должен запускаться после !?
Как / где я бы вызвал BeginCheck () после загрузки, чтобы убедиться, что файл был загружен?
Вот как я определилкласс Uploader:
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);
}
}
}