代码之家  ›  专栏  ›  技术社区  ›  John Sheehan

异步web请求回调中未更新UI

  •  3
  • John Sheehan  · 技术社区  · 14 年前

    我用它来做一个网络请求并下载一些数据:

    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"));
        }
    }
    

    的文本 textBlock1 e.Result 有正确的数据。如何从回调中更新?

    编辑: 如果我加上 MessageBox.Show(e.Result);

    再次编辑:

    6 回复  |  直到 14 年前
        1
  •  4
  •   Sergey Zwezdin    14 年前

        2
  •  2
  •   Jacob    14 年前

    在更新来自不同调度器的UI时,我也遇到了一些问题。我最后做的是使用TextBlock(或其他UI元素)自己的dispatcher,这对我很有用。我认为phone框架可能在app和UI元素之间使用了不同的调度器。注意从dispatcher.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"));
    }
    
        3
  •  2
  •   John Sheehan    14 年前

        4
  •  1
  •   TheTodd    14 年前

    client.DownloadStringAsync需要如下Uri:

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

    另外,您不应该通过Dispatcher.BeginInvoke更新TextBlock吗

        client.DownloadStringCompleted += (s, e) => 
        { 
            if (null == e.Error) 
                Dispatcher.BeginInvoke(() => UpdateStatus(e.Result)); 
            else 
                Dispatcher.BeginInvoke(() => UpdateStatus("Operation failed: " + e.Error.Message)); 
        };
    
        5
  •  1
  •   Daniel Crenna    14 年前
    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"));
        }
    }
    
        6
  •  1
  •   Ben Gracewood    14 年前

    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());
    }