httpwebrequest をマルチスレッド化しようとしています。応答を返す必要はありません。できるだけ早く送信する必要があるだけです。現在、私はタスクを使用していますが、接続速度ではなくシステム仕様を使用してスレッドを決定するため、明らかに最も効率的な方法ではありません。
したがって、私が尋ねようとしているのは、PC のコア数ではなく、接続速度に基づいてスレッドを使用する最も効果的な方法は何かということだと思います。
ありがとう
httpwebrequest をマルチスレッド化しようとしています。応答を返す必要はありません。できるだけ早く送信する必要があるだけです。現在、私はタスクを使用していますが、接続速度ではなくシステム仕様を使用してスレッドを決定するため、明らかに最も効率的な方法ではありません。
したがって、私が尋ねようとしているのは、PC のコア数ではなく、接続速度に基づいてスレッドを使用する最も効果的な方法は何かということだと思います。
ありがとう
BeginGetResponse()
のメソッドであるメソッドをasync
使用できますWebRequest
。
ワーカーのキューを作成し、実行中のワーカーをディクショナリで追跡し、実行中のワーカーが終了すると新しいワーカーを起動することをお勧めします。これにより、アクティブなワーカーの数を調整できます。また、停止メッセージを送信する必要がある場合に備えて、アクティブなワーカーのコレクションも提供します。
これを app.config に追加して、デフォルトの接続制限である 2 つを超える必要があります。
<system.net>
<connectionManagement>
<remove address="*"/>
<add address="*" maxconnection="10" />
</connectionManagement>
</system.net>
次の例では、コールバックを使用してキューからワーカーを削除しMonitor
、待機中のワーカー キューを空にすることをゲートします。
using System;
using System.Collections.Generic;
using System.Threading;
namespace Demo
{
class Program
{
static Queue<Worker> waitingWorkers = new Queue<Worker>();
static Dictionary<int, Worker> activeWorkers = new Dictionary<int, Worker>();
static int maxThreads = 10;
static object waitLock = new object();
static void Main(string[] args)
{
for (int i = 0; i < 100; i++)
{
waitingWorkers.Enqueue(new Worker(new WorkerDoneDelegate(WorkerDone)));
}
lock (waitLock)
{
while (waitingWorkers.Count > 0)
{
if (activeWorkers.Count > maxThreads)
{
Monitor.Wait(waitLock);
}
Worker worker = waitingWorkers.Dequeue();
Thread thread = new Thread(worker.SendSomething);
thread.IsBackground = true;
activeWorkers[thread.ManagedThreadId] = worker;
thread.Start();
}
}
Console.WriteLine("Queue empty");
Console.ReadKey();
}
static void WorkerDone()
{
lock (waitLock)
{
activeWorkers.Remove(Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("Worker done - id=" + Thread.CurrentThread.ManagedThreadId.ToString());
Monitor.Pulse(waitLock);
}
}
public delegate void WorkerDoneDelegate();
public class Worker
{
static Random rnd = new Random();
WorkerDoneDelegate Done;
public Worker(WorkerDoneDelegate workerDoneArg)
{
Done = workerDoneArg;
}
public void SendSomething()
{
Console.WriteLine("Worker send - id=" + Thread.CurrentThread.ManagedThreadId.ToString());
Thread.Sleep(rnd.Next(1, 1000));
Done();
}
}
}
}
または、単に Parallel.For/ForEach を使用すると、スレッドの最適化が行われます (プーリング サイズ、スレッド数などを選択します)。