[FIXED] Die Änderung der WPF-Ansicht verursacht Verzögerungen

Ausgabe

Ich habe zwei Ansichten in meine Anwendung geschrieben, und wenn ich von “Home” zu “Details” wechsle, verursacht dies eine Verzögerung von etwa 0,5 – 1 Sekunde. Ich verstehe, dass der Grund meine API-Aufrufe im Konstruktor sind, aber ich habe Threading hinzugefügt und zuerst leere Eigenschaften ausgefüllt, und nachdem die Threads fertig sind, sollte es eine OnPropertyChange auslösen. Mein Ansichtsmodell “Details” ist hier

public class DetailsViewModel : ObservableObject
{
    private ObservableCollection<Market> _markets;
    private Asset _asset;
    private readonly Uri _baseUri = new Uri("https://cryptingup.com/api/assets/");
    public RestClient Client { get; set; }

    public ObservableCollection<Market> Markets
    {
        get
        {
            return _markets;
        }
        set
        {
            _markets = value;
            OnPropertyChanged();
        }
    }
    public Asset Asset
    {
        get
        {
            return _asset;
        }
        set
        {
            _asset = value;
            OnPropertyChanged();
        }
    }

    public DetailsViewModel(string id)
    {
        Client = new RestClient();
        Markets = new ObservableCollection<Market>();

        new Thread(() =>
        {
            RequestCurrencyDetails(id);
        })
        {
            IsBackground = true
        }.Start();
        RequestAllMarkets(id);

        new Thread(() =>
        {
            RequestAllMarkets(id);
        })
        {
            IsBackground = true
        }.Start();
    }

    private void RequestCurrencyDetails(string id)
    { 
        Uri uri = new Uri(_baseUri, id);
        var request = new RestRequest(uri.ToString());
        request.AddHeader("Accept", "application/json");
        request.AddHeader("Content-Type", "application/json");

        var response = Client.GetAsync(request).GetAwaiter().GetResult();
        var curemodel = JsonConvert.DeserializeObject<CurrencyModelCU>(response.Content);
        Asset = curemodel.Asset;
    }
    private void RequestAllMarkets(string id)
    {
        string marketPath = id + "/markets";
        Uri uri = new Uri(_baseUri, marketPath);

        var request = new RestRequest(uri.ToString());
        request.AddHeader("Accept", "application/json");
        request.AddHeader("Content-Type", "application/json");

        var response = Client.GetAsync(request).GetAwaiter().GetResult();
        var marmodel = JsonConvert.DeserializeObject<MarketsModel>(response.Content);


        ObservableCollection<Market> temp = new ObservableCollection<Market>();
        for (int i = 0; i < 10; i++)
        {
            temp.Add(marmodel.Markets[i]);
        }
        Markets = temp;
    }
}

Ich weiß, dass ich hier beim Einfädeln etwas falsch gemacht habe, aber ich komme selbst nicht auf den Grund. Danke für die Antwort

Lösung

Ich empfehle dringend, await asyncanstelle von Thread. Wird auch RequestAllMarkets(id);synchron aufgerufen. Dies verursacht höchstwahrscheinlich die “Verzögerung”.

Hier ist ein Beispiel, wie Task.RunSie den Ladevorgang “feuern und vergessen”.
https://dotnetfiddle.net/sK3ivq

using System;
using System.Threading;
using System.Diagnostics;
using System.Threading.Tasks;
                    
public class Program
{
    public static void Main()
    {
        Console.WriteLine("start");
        
        Stopwatch sw = new Stopwatch();
        sw.Start();
        DetailsViewModel vm = new DetailsViewModel();
        
        Console.WriteLine($"already back from ctor -> no lag. prove: {sw.ElapsedMilliseconds}ms foo:{vm.Foo}");
        
        // we use thread sleep -> in wpf app you don't have to wait because property change took place in VM.
        Thread.Sleep(1000);
        Console.WriteLine($"we waited long enough...: {sw.ElapsedMilliseconds}ms foo:{vm.Foo}");
    }
    
    public class DetailsViewModel
    {
        public DetailsViewModel()
        {
            Foo= "not initialized";
            Task.Run(()=> Init());
        }
        
        public async Task Init()
        {
            await Task.Delay(500);
            Foo = "bar";
        }
        
        public string Foo {get;set;}
    }
}


Beantwortet von –
Mat


Antwort geprüft von –
Willingham (FixError Volunteer)

0 Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like