Entity Framework dlaczego ToListAsync() blokuje UI

0

Dlaczego ten kod blokuje UI w wpf:

public async Task<IEnumerable<Group>> GetAll()
 {
         return await Context.Groups.ToListAsync();                  
 }

Dopiero jak zrobie tak to jest ok:

public async Task<IEnumerable<Group>> GetAll()
{
       return await Task.Run(() => { return Context.Groups.ToListAsync(); });                 
}
0

Czemu ostanio WPF stał sie tutaj taki popularny?

0

Pokaż coś więcej tego kodu, gdzie i jak wywołujesz tą metodę, nie wstydź się :) . Co do metody to bez sensu jest taki zapis return await. Await jest po to, żeby wykonać kontynuację po zakończeniu długotrwałej operacji, ale skoro niczego dalej nie wykonujesz to po prostu zwróć Taska bez await

0

Całość wyglada tak:

private async void OnOpenMainContentView(OpenDetailViewEventArgs args)
        {
                 //...
                await mainContentViewModel.LoadAsync(args.Id);
                //...
        }
public async override Task LoadAsync(int id)
        {
            Groups = await _unitOfWork.Groups.GetAll();
        }
public async Task<IEnumerable<Group>> GetAll()
        {
            return Context.Groups.ToListAsync();          //tutaj blokuje mi UI        
        }
0

w ostatniej linii zle skopiowalem, mam:

return await Context.Groups.ToListAsync();          //tutaj blokuje mi UI     

ale nie mogę już edytować.

0

Tego kodu i tak jest za mało, żeby znaleźć przyczynę. Ale wątpie, że to w tym miejscu. ToListAsync nie zablokuje Ci UI bo wykonuje się na osobnym wątku. Wgl. co rozumiesz przez zablokowanie UI? Może chodzi Ci o to, że nie wyświetla Ci od razu tych danych tylko po jakimś czasie? No ale to normalne bo musi przecież pobrać te dane. No chyba że nie możesz wgl. ruszyć okienkiem no to wtedy jest zablokowane. Musiałbyś podebugować ten kod, ustawić w odpowiednim miejscu breakpointy i sprawdzić czy dany kod, który mógłby zablokować główny wątek czy wykonuje się na osobnym wątku. W zakładce debug->windows->threads możesz sobie uruchomić okienko gdzie możesz sprawdzać jaki wątek jest wykonywany przy danym breakpoincie. Tylko, że musiałbyś to zrobić w odpowiedni sposób.

0
Manuel.Artificer napisał(a):

Tego kodu i tak jest za mało, żeby znaleźć przyczynę. Ale wątpie, że to w tym miejscu. ToListAsync nie zablokuje Ci UI bo wykonuje się na osobnym wątku. Wgl. co rozumiesz przez zablokowanie UI? Może chodzi Ci o to, że nie wyświetla Ci od razu tych danych tylko po jakimś czasie? No ale to normalne bo musi przecież pobrać te dane. No chyba że nie możesz wgl. ruszyć okienkiem no to wtedy jest zablokowane. Musiałbyś podebugować ten kod, ustawić w odpowiednim miejscu breakpointy i sprawdzić czy dany kod, który mógłby zablokować główny wątek czy wykonuje się na osobnym wątku. W zakładce debug->windows->threads możesz sobie uruchomić okienko gdzie możesz sprawdzać jaki wątek jest wykonywany przy danym breakpoincie. Tylko, że musiałbyś to zrobić w odpowiedni sposób.

Zamiescilem caly kod. Blokowanie UI czyli inaczej zamraza mi UI, nie moge kliknac nic itp.

0

Na staku piszą że łączenie się z bazą i nie które inne operacja nie są threadsafty i blokują wątek. Rozwiązaniem jest tak Ty to zrobiłeś użycie Task.Run.

0

Można też starą, dobrą metodą z dispatcherem:

ThreadPool.QueueUserWorkItem(delegate
{
	// Pobranie danych z bazy

	App.Current.Dispatcher.BeginInvoke(new Action(() =>
	{
		// Propagacja do gui
		// czyli np. zasielenie zbindowanej do DataGrid'a kolekcji.
	}));
});

Należy jeszcze pamiętać o tym, że jeżeli chcemy łapać wyjątki w takim kodzie to należy robić to w ciele QueueUserWorkItem np:

ThreadPool.QueueUserWorkItem(delegate
{
	try
	{
		// Pobranie danych z bazy

		App.Current.Dispatcher.BeginInvoke(new Action(() =>
		{
			// Propagacja do gui
			// czyli np. zasielenie zbindowanej do DataGrid'a kolekcji.
		}));
	}
	catch(Exception ex)
	{
		// Obsługa wyjątku
	}
});

1 użytkowników online, w tym zalogowanych: 0, gości: 1