EPIDEMIASH
@EPIDEMIASH
Человек швейцарский нож

Что делаю не верно?

Магистры C# подскажите, как сделать.

В моем приложении подгружаются данные о пользователе из Active Directory,
в одной части подгружаются атрибуты,
в другой подгружается список групп.

Как правило, группы подгружаются дольше и первая часть не отобразится, пока не подгрузятся группы.
Из-за этого я засунул в отдельный метод подгрузку групп, в котором через Invoke воткнул в отдельный поток.

new Thread(() =>
Invoke((MethodInvoker)(() =>
{
// мой код
}));
}).Start();


В итоге вроде как поток создается, но ситуацию это не изменило.
Жду подгрузку групп, а потом вываливаю все разом.

=========================== UPD ===========================

На форме 2 области, в первой выливаются в label'ы значения атрибутов УЗ, во второй области списком подгружаются группы этой УЗ.

1 вариант, который был: При клике в стандартном системном потоке, идет подгрузка атрибутов, потом на форме видно как полоска скроллинга списка групп меняется, когда список групп до конца подгружен, этот список отображается + появляются значения атрибутов на форме(прорисовываются).

2 вариант, как по мне грубый: Я засунул в отдельный метод эти 2 действия, внутри обернув в отдельный поток. Перед запуском метода, написал CheckForIllegalCrossThreadCalls = false; и дополнительно обернул подгрузку атрибутов в await Task.Run.
За счет чего, разрешил обращаться к контролам формы из других потоков. В таком варианте, 1 часть мгновенно загружается, а вторая потом подгружается. НО из-за подгрузки второй части, я все равно не могу например перемещать форму, так как выполняется подгрузка.

3 вариант, я решил написать сюда: Опять же разделил на 2 метода, эти 2 операции (подгрузка атрибутов, подгрузка групп).

Сейчас я имею:

private void LoadingAttributes(string Login) {} // Подгрузка атрибутов
async void LoadingGroups(string Login) {} // Подгрузка групп

1-й выполняется в основном потоке, так как он это производит мгновенно
2-й внутри, выполняется в отдельном потоке, вот что внутри LoadingGroups

await Task.Run(() =>
{
// ставлю в очередь мой код, где идет подгрузка списка в listview,
});

new Thread(() =>
Invoke((MethodInvoker)(() =>
{
LoadingAttributes(Login); // подгрузка атрибутов в label'ы
}));
}).Start();


Но он также работает тольк с паре с CheckForIllegalCrossThreadCalls = false;
  • Вопрос задан
  • 155 просмотров
Решения вопроса 2
@Voland69
  1. async/await говорят о том, что метод может быть выполнен асинхронно, но не гарантируют этого
  2. new Tread() создает поток, который что-то делает. поток по умолчанию выполняется параллельно с GUI Event Loop, и чтобы вернуть данные коду внутри потока можно передать коллбэк, который будет выполнен после длительной операции
  3. Invoke() ЕМНИП служит для синхронизации бэкграунд потока с GUI (просто так из фона нельзя обновлять данные на форме), в него нужно помещать не весь код, а только тот код, который полученные в фоне данные отправляет форме
  4. если метод не умеет выдавать данные не разом, а по мере загрузки, интерактивное появление новых данных на форме не получится
  5. если Вы полностью контролируете загрузку данных, можно сделать на событиях синхронизацию с GUI - загрузчик кидает событие onDataRecieved а форма на него подписана и обновляет свои данные
Ответ написан
Комментировать
freeExec
@freeExec
Участник OpenStreetMap
await LoadingAttributes();
ShowAttributes();
await LoadingGroups();
ShowGroups();
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@AndromedaStar
.Net - monkey
Если это десктопное приложение, что вроде бы Invoke выполняется в главном потоке.
Я что-то такое помню.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы