Вы можете пропустить эту часть:
Я создаю приложение, в котором клиент должен найти сервер в той же сети.
Сервер:
public static void StartListening (порт Int32) {
TcpListener server = new TcpListener(IP.GetCurrentIP(), port);
server.Start();
Thread t = new Thread(new ThreadStart(() =>
{
while (true)
{
// wait for connection
TcpClient client = server.AcceptTcpClient();
if (stopListening)
{
break;
}
}
}));
t.IsBackground = true;
t.Start();
}
Допустим, серверпрослушивает порт 12345
, затем клиент:
- получает текущий IP-адрес клиента, скажем, 192.168.5.88
создать список всех возможных IP-адресов.IP-адрес сервера, вероятно, будет связан с IP-адресом клиента, если они находятся в одной локальной сети, поэтому я создаю список следующим образом:
192.168.5.0
192.168.5.1
192.168.5.2
192.168.5.3
.....etc
.....
192.168.0.88
192.168.1.88
192.168.2.88
192.168.3.88
...etc
192.0.5.88
192.1.5.88
192.2.5.88
192.3.5.88
192.4.5.88
..... etc
0.168.5.88
1.168.5.88
2.168.5.88
3.168.5.88
4.168.5.88
.... etc
Затем я пытаюсь соединиться со всеми возможнымиip и порт 12345. Если одно соединение успешно, то это означает, что я нашел адрес сервера.
Теперь мой вопрос:
Теперь я сделал это двумя способами,Я знаю только основы о потоках, и я не знаю, опасно ли это, но это работает очень быстро.
// first way
foreach (var ip in ListOfIps)
{
new Thread(new ThreadStart(() =>
{
TryConnect(ip);
})).Start();
}
второй способ, который я считаю, это более безопасно, но это занимает гораздо больше времени:
// second way
foreach (var ip in ListOfIps)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(TryConnect), ip);
}
Мне нужно вызывать метод TryConnect около 1000 раз, и каждый раз это занимает около 2 секунд (я установил тайм-аут соединения на 2 секунды).Какой будет самый эффективный и безопасный способ назвать его 1000 раз?
РЕДАКТИРОВАТЬ 2
Вот результаты с использованием различных методов:
1) Использование пула потоков
..
..
var now = DateTime.Now;
foreach (var item in allIps)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork), item);
}
ThreadPool.QueueUserWorkItem(new WaitCallback(PrintTimeDifference), now);
}
static void PrintTimeDifference(object startTime)
{
Console.WriteLine("------------------Done!----------------------");
var s = (DateTime)startTime;
Console.WriteLine((DateTime.Now-s).Seconds);
}
![enter image description here](https://i.stack.imgur.com/IdUSD.png)
Потребовалось 37 секунд для завершения
2) Использование потоков:
..
..
var now = DateTime.Now;
foreach (var item in allIps)
{
new Thread(new ThreadStart(() =>
{
DoWork(item);
})).Start();
}
ThreadPool.QueueUserWorkItem(new WaitCallback(PrintTimeDifference), now);
![enter image description here](https://i.stack.imgur.com/fBaFU.png)
Потребовалось 12 секунд, чтобы завершить
3) Использование задач:
..
..
var now = DateTime.Now;
foreach (var item in allIps)
{
var t = Task.Factory.StartNew(() =>
DoWork(item)
);
}
ThreadPool.QueueUserWorkItem(new WaitCallback(PrintTimeDifference), now);
}
static void PrintTimeDifference(object startTime)
{
Console.WriteLine("------------------Done!----------------------");
var s = (DateTime)startTime;
Console.WriteLine((DateTime.Now-s).Seconds);
}
![enter image description here](https://i.stack.imgur.com/xQHkO.png)
Это заняло 8 секунд !!