The user interface is not updated in the asynchronous web request callback

I use this to make a web request and upload some data:

public partial class MainPage : PhoneApplicationPage
{
    public MainPage()
    {
        InitializeComponent();

        var client = new WebClient();

        client.DownloadStringCompleted += (s, e) => {
            textBlock1.Text = e.Result;
        };

        client.DownloadStringAsync(new Uri("http://example.com"));
    }
}

The text textBlock1never changes, even if it e.Resulthas the correct data. How do I update this from a callback?

Edit: if I add MessageBox.Show(e.Result);to the callback along with the destination textBlock1.Text, both the messsage field and the text field display the correct data.

Edit again: if I add a TextBox and set its text immediately after the line textBlock1.Text, they both display the correct text.

+3
source share
6 answers

WP7 , . ATI Radeon HD 3400 , , .

+2

, .

+4

. , , , TextBlock ( ), . , . .BeginInvoke textbox1.Dispatcher...

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    var dispatcher = Deployment.Current.Dispatcher;

    var client = new WebClient();

    client.DownloadStringCompleted += (s, e) =>
    {
        var result = e.Result;
        textBlock1.Dispatcher.BeginInvoke(
            ()=> textBlock1.Text = result
            );
    };

    client.DownloadStringAsync(new Uri("http://example.com"));
}
+2

client.DownloadStringAsync Uri :

client.DownloadStringAsync(new Uri("http://example.com"));

, TextBlock Dispatcher.BeginInvoke :

    client.DownloadStringCompleted += (s, e) => 
    { 
        if (null == e.Error) 
            Dispatcher.BeginInvoke(() => UpdateStatus(e.Result)); 
        else 
            Dispatcher.BeginInvoke(() => UpdateStatus("Operation failed: " + e.Error.Message)); 
    };
+1
public partial class MainPage : PhoneApplicationPage
{
    public MainPage()
    {
        InitializeComponent();

        Loaded += MainPage_Loaded;
    }

    void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        var dispatcher = Deployment.Current.Dispatcher;

        var client = new WebClient();

        client.DownloadStringCompleted += (s, e) =>
        {
            var result = e.Result;
            dispatcher.BeginInvoke(
                ()=> textBlock1.Text = result
                );
        };

        client.DownloadStringAsync(new Uri("http://example.com"));
    }
}
+1

, . , . , DownloadStatus, , , .

, ViewModel OpenReadCompleted. . PropertyChanged , , .

, , , , !

Here is a snippet of my irreproducible code. The user interface text block tied to "DownloadStatus" is happily updated properly throughout. But the same paradigm does not work in my main project. Rabies!

public void BeginDownload(bool doWorkAfterDownload)
{
    DownloadStatus = "Starting ...";

    _doExtraWork = doWorkAfterDownload;
    var webClient = new WebClient();

    string auth = "Basic " + Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("test:password"));
    webClient.Headers["Authorization"] = auth;

    webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(webClient_DownloadProgressChanged);
    webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);

    webClient.OpenReadAsync(new Uri("http://www.ben.geek.nz/samsung1.jpg"));
}

void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
    if (e.Error != null)
    {
        DownloadStatus = e.Error.Message;
        return;
    }

    DownloadStatus = "Completed. Idle.";

    if(_doExtraWork)
    {
        Thread t = new Thread(DoWork);
        t.Start(e.Result);
    }

}

void DoWork(object param)
{
    InvokeDownloadCompleted(new EventArgs());

    // just do some updating
    for (int i = 1; i <= 10; i++)
    {
        DownloadStatus = string.Format("Doing work {0}/10", i);
        Thread.Sleep(500);
    }
    DownloadStatus = "Completed extra work. Idle.";
    InvokeExtraWorkCompleted(new EventArgs());
}
+1
source

Source: https://habr.com/ru/post/1754348/


All Articles