0

I new to WPF, and have to put a basic application together

It consists of one main window with a frame, and one page the page has a basic status text -

the requirement is that when the page loads up, the application has to do a bunch of REST call to fetch some data from remote source, and update the status text as it fetches

problem is, as I update the text, it doesn't seem to be reflected on the page, or maybe it's being blocked - even though I've used Task

so far, I have the following code for testing:

 private void Page_Loaded(object sender, RoutedEventArgs e) {
        var wnd = Window.GetWindow(this);
        wnd.ContentRendered += Wnd_ContentRendered;            
    }

    private void Wnd_ContentRendered(object sender, EventArgs e) {
        DisplayMessages();            
    }

    private void DisplayMessages() {
        authenticationText.Text = "text one";
        var t = Task.Delay(5000);
        t.Wait();
        authenticationText.Text = "text two";
        t = Task.Delay(5000);
        t.Wait();
        authenticationText.Text = "text three";
        t = Task.Delay(5000);
        t.Wait();
    }

even though I'm waiting after each task, the UI doesn't get updated - rather it just displays text three directly after method is finished - suggestions ?

P.S: there's also a WPF loader on that page, I've noticed that it doesn't get animated as well - it seems the delay is working but everything on the UI isn't updated

Danish
  • 741
  • 4
  • 17
  • 31
  • Do you implement ` InotifyPropertyChanged`? – Leonid Malyshev Aug 08 '16 at 06:49
  • not yet, I'm having a play with async / await - I've gotten around the UI thread lock problem, just checking with the REST Calls and error handling see how that looks, I'll post the solution here when it's working – Danish Aug 08 '16 at 07:04

3 Answers3

1

I would suggest for getting the data from REST implementation , you should use the background worker and on the basis of completion of thread or progress changed you need to update the UI thread accordingly.

for getting the better insights on background worker.. kindly use this link

How to use WPF Background Worker

In your case you can use progresschanged event of the backgroundworker..

Please Create some property lets say StatusText with InotifyPropertyChanged Interface implemented and bind (use TwoWay Binding) it with the Text property of the authenticationText control .... and in the progress changed event of the backgroundworker set the value of the StatusText property,., which will automatically updates the UI.

Community
  • 1
  • 1
Ashok Rathod
  • 840
  • 9
  • 24
1

You could try to invoke these results on the UI Thread... Run your task normally with Task.Run or whatever. Each time you are ready to set some property on UI Thread you should invoke it through the dispatcher..

    Task.Run(() =>
    {
        var _Temp = getSomePropTask();
        Thread.Sleep(1000);
        App.Current.Dispatcher.Invoke(()=>{
            authenticationText.Text = _Temp;
        });
    });
jsandv
  • 276
  • 4
  • 20
0

Thanks to suggestion by Ashok, I did some background reading and have come up with the following solution using Task, async and await - which is simpler to manage than background worker threads:

private void Page_Loaded(object sender, RoutedEventArgs e) {
    var wnd = Window.GetWindow(this);
    wnd.ContentRendered += Wnd_ContentRendered;            
}

private void Wnd_ContentRendered(object sender, EventArgs e) {
    GetDataAsync();            
}

 private async void GetDataAsync() {
        authenticationText.Text = "Connecting...";
        await Task.Delay(5000);
        authenticationText.Text = "Getting Member Details...";
        List<MemberServiceModel> memberList = await GetMembersAsync();

        // more code for handling response
}


private List<MemberServiceModel> GetMembers() {
            //get all members synchronous
            var request = new RestRequest("Members/Admin", Method.GET);
            var response = _client.Execute<List<MemberServiceModel>>(request);
            if (response.ResponseStatus != ResponseStatus.Completed) {
                //TODO
                _restErrorStatus = response.ResponseStatus.ToString();
                _restErrorMessage = response.StatusDescription;
                _logger.Error("Error in GetMembers");
                _logger.Error("Status:" + _restErrorStatus);
                _logger.Error("Description:" + _restErrorMessage);
            }
            return response.Data; ;
        }

        private Task<List<MemberServiceModel>> GetMembersAsync() {
            //get all members asynchronous
            return Task.Run(new Func<List<MemberServiceModel>>(GetMembers));
        }
Danish
  • 741
  • 4
  • 17
  • 31