Christopher Smit Ответов: 2

Вопрос о нитках и нужно ли это.


Хороший день,

У меня есть довольно простой вопрос. Я новичок в потоках и задавался вопросом, стоит ли использовать его с моим нижеприведенным сценарием.

В основном у меня есть программа на C#, которая еще не протестирована. Когда программа запускается, она будет отправлять массовые sms-сообщения на разные мобильные телефоны с помощью API-вызовов на сервер. При отправке требуется, чтобы звонок был сделан для каждого отправляемого номера. Это, очевидно,означает цикл foreach.

Мой первый вопрос таков:
Когда программа выполняет этот код, будет ли он блокировать главное окно программы и препятствовать пользователю выполнять другую работу над программой? Нужно ли пользователю ждать завершения отправки?

Второй Вопрос:
Должен ли я использовать поток для запуска метода в фоновом режиме или я неправильно понимаю смысл потока? Есть ли другой способ сделать это без блокировки формы?

Простите меня, если это простые вопросы, но простые попытки узнать и найти больше понимания в этом.

С уважением

Что я уже пробовал:

Я пробовал читать статьи о потоках, но не могу понять, действительно ли это то, что мне нужно

2 Ответов

Рейтинг:
7

Afzaal Ahmad Zeeshan

Цитата:
Когда программа выполняет этот код, будет ли он блокировать главное окно программы и препятствовать пользователю выполнять другую работу над программой? Нужно ли пользователю ждать завершения отправки?
OG был немного коротким, длинный ответ заключается в том, что любая операция, требующая операции ввода — вывода — включая, но не ограничиваясь сетевым вводом-выводом, дисковым вводом-выводом и т. д. Даже загрузка растровых изображений изображения будет причиной здесь-всегда приведет к замораживанию вашего приложения. Это происходит потому, что элемент управления был передан сборке, управляющей операцией ввода-вывода, и вашему приложению придется ждать завершения этой операции, прежде чем оно сможет фактически выполнять другие операции, такие как "и особенно" обработка взаимодействия с пользователем. В основном, решение является просто случаем следующей функции-структуры,
public async void IOFunction() {
   // Code..
   // Almost every object has async functionality in .NET and WinRT
   await Obj.DoJobAsync();
   // Code.
}

Таким образом, Вы сможете обрабатывать взаимодействие с пользователем и по-прежнему выполнять задачу ввода-вывода на бэкэнде. Это похоже на обладание особыми, Thread, Task или BackgroundWorker объекты, но гораздо более простым способом.

Для большего: Асинхронное программирование с помощью async и await (C#)[^]
Цитата:
Должен ли я использовать поток для запуска метода в фоновом режиме или я неправильно понимаю смысл потока? Есть ли другой способ сделать это без блокировки формы?
То, что сказал ОГ, верно, но я не рекомендую полагаться только на это. Вместо этого я бы рекомендовал не использовать Thread себя. Вместо этого просто используйте Task объект. Моя рекомендация состоит в том, чтобы просто принять асинхронный/ожидающий паттерн программирования. Нет никакой необходимости идти в глубину Thread, или с помощью Task или с помощью BackgroundWorker объект или создать для этого свой собственный механизм. Способ обработки асинхронных задач C#действительно удобен, и я лично наслаждался своей жизнью с тех пор, как начал его использовать.

Оговорка: Шаблон Async/await действительно сложен для начинающих из-за структуры bi-function-declaration. Но как только вы поймете это, это будет удивительно для вас. Забудьте о нитях, вам вообще не нужно их использовать.


Karthik_Mahalingam

5

Afzaal Ahmad Zeeshan

Спасибо, Картик.

Рейтинг:
13

OriginalGriff

Цитата:
Когда программа выполняет этот код, будет ли он блокировать главное окно программы и препятствовать пользователю выполнять другую работу над программой? Нужно ли пользователю ждать завершения отправки?

Да. И да.

Цитата:
Должен ли я использовать поток для запуска метода в фоновом режиме или я неправильно понимаю смысл потока? Есть ли другой способ сделать это без блокировки формы?

Да и нет, вы не ошиблись. И нет.

Вероятно, я настроил бы поток для выполнения фактической отправки и кормил бы его из очереди< T> через блокировку. Если в очереди что-то есть, поток получает это, разбирается с этим и снова проверяет. Когда он пуст, поток засыпает на секунду или минуту, а затем снова проверяет.

"
Цитата:
Спасибо за разъяснение. Темы кажутся пугающими, показывая множество различных способов сделать это через интернет. Я попробовал сделать просто Thread autoSend = new Thread(_viewModel_API.SendMessagesToListOfClients());

Но я явно упускаю всю логику, стоящую за этим, поскольку ничего не посылается. (Ну, на данный момент он должен только всплывать сообщение для тестирования)
"


Попробовать это:
private void myButton_Click(object sender, EventArgs e)
    {
    Thread worker1 = new Thread(MyMethod);
    worker1.Start("Hello");
    Thread worker2 = new Thread(MyMethod);
    worker2.Start("Hello There");
    Thread worker3 = new Thread(MyMethod);
    worker3.Start("Hello There Again");
    }

private void MyMethod(object message)
    {
    string s = message as string;
    if (s != null)
        {
        Console.WriteLine(s);
        Thread.Sleep(5000);
        Console.WriteLine("{0} - Completed", s);
        }
    }

Он запускает три потока, которые делают одно и то же с разными данными.
И вы получаете что-то вроде этого:
Hello
Hello There
Hello There Again
The thread 0x15c8 has exited with code 259 (0x103).
The thread 0x7ac has exited with code 259 (0x103).
The thread 0x1e2c has exited with code 259 (0x103).
Hello - Completed
Hello There Again - Completed
Hello There - Completed

Я не предлагаю вам делать это таким образом - вам нужно отправлять сообщения одно за другим, а не пытаться отправить их все сразу, так как у вас есть только одно устройство для их отправки. Таким образом, вам нужна одна дополнительная нить с петлей в ней, но это должно дать вам представление.
Обратите внимание, что в этом примере потоки не заканчивались в том порядке, в котором они были запущены, - этого и следовало ожидать, поскольку Windows-это многозадачная система.


Christopher Smit

Спасибо за разъяснение. Темы кажутся пугающими, показывая множество различных способов сделать это через интернет. Я попробовал сделать просто Thread autoSend = new Thread(_viewModel_API.SendMessagesToListOfClients());

Но я явно упускаю всю логику, стоящую за этим, поскольку ничего не посылается. (Ну, на данный момент он должен только всплывать сообщение для тестирования)

OriginalGriff

Ответ обновлен.

Christopher Smit

В итоге я решил сделать следующее:

ВАР отправить = новый поток(() =&ГТ; { значение = _viewModelAPI.SendDailyBirthdayMessages(); });
Отправить.Начать();

но он по-прежнему запирал мою форму. Потом я заметил, что добавил нитку.Сон (2000); в моем методе и после его удаления форма больше не заперта. Спасибо!!

OriginalGriff

Пожалуйста!