Как мне обновить свой пользовательский интерфейс из HttpWebRequest.Запускаем поток запросов в Silverlight
-
08-06-2019 - |
Вопрос
Я загружаю несколько файлов, используя BeginGetRequestStream HttpWebRequest, но я хочу обновить контроль выполнения, который я написал, пока я публикую поток данных.
Как это должно быть сделано, я попытался вызвать Dispatch.BeginInvoke (как показано ниже) изнутри цикла, который загружает данные в поток, но он блокирует браузер до его завершения, так что, похоже, он находится в какой-то тупиковой ситуации рабочего потока / пользовательского интерфейса.
Это фрагмент кода в значительной степени того, что я делаю:
class RequestState
{
public HttpWebRequest request; // holds the request
public FileDialogFileInfo file; // store our file stream data
public RequestState( HttpWebRequest request, FileDialogFileInfo file )
{
this.request = request;
this.file = file;
}
}
private void UploadFile( FileDialogFileInfo file )
{
UriBuilder ub = new UriBuilder( app.receiverURL );
ub.Query = string.Format( "filename={0}", file.Name );
// Open the selected file to read.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create( ub.Uri );
request.Method = "POST";
RequestState state = new RequestState( request, file );
request.BeginGetRequestStream( new AsyncCallback( OnUploadReadCallback ), state );
}
private void OnUploadReadCallback( IAsyncResult asynchronousResult )
{
RequestState state = (RequestState)asynchronousResult.AsyncState;
HttpWebRequest request = (HttpWebRequest)state.request;
Stream postStream = request.EndGetRequestStream( asynchronousResult );
PushData( state.file, postStream );
postStream.Close();
state.request.BeginGetResponse( new AsyncCallback( OnUploadResponseCallback ), state.request );
}
private void PushData( FileDialogFileInfo file, Stream output )
{
byte[] buffer = new byte[ 4096 ];
int bytesRead = 0;
Stream input = file.OpenRead();
while( ( bytesRead = input.Read( buffer, 0, buffer.Length ) ) != 0 )
{
output.Write( buffer, 0, bytesRead );
bytesReadTotal += bytesRead;
App app = App.Current as App;
int totalPercentage = Convert.ToInt32( ( bytesReadTotal / app.totalBytesToUpload ) * 100 );
// enabling the following locks up my UI and browser
Dispatcher.BeginInvoke( () =>
{
this.ProgressBarWithPercentage.Percentage = totalPercentage;
} );
}
}
Решение
Я собирался сказать, что я не думал, что HttpWebRequest в Silverlight 2 поддерживает потоковую передачу, потому что данные запроса полностью буферизуются в памяти.Однако прошло много времени с тех пор, как я просматривал его в последний раз, поэтому я вернулся, чтобы посмотреть, поддерживает ли его бета-версия 2.Что ж, оказывается, так оно и есть.Я рад, что вернулся и прочитал, прежде чем заявлять об этом.Вы можете включить его, установив для параметра AllowReadStreamBuffering значение false.Вы установили это свойство в своем HttpWebRequest?Это может быть причиной вашей блокировки.
Отредактируйте, нашел для вас еще одну ссылку.Возможно, вы захотите последовать этому подходу, разбив файл на фрагменты.Это было написано в марте прошлого года, поэтому я не уверен, будет ли это работать в бета-версии 2 или нет.
Другие советы
Спасибо за это, я взгляну на эти ссылки, я все равно рассматривал возможность разбиения моих данных на части, кажется, это единственный способ получить какие-либо разумные отчеты о ходе работы.