Du har ret - der er brug for lock i main thread også.
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
namespace E
{
public class Program
{
public delegate void IncrementDuplicate();
public class Param
{
private string host;
private Dictionary<string, IPAddress[]> table;
private IncrementDuplicate p;
public Param(string host, Dictionary<string, IPAddress[]> table, IncrementDuplicate p)
{
this.host = host;
this.table = table;
this.p = p;
}
public string Host { get { return host; } }
public Dictionary<string, IPAddress[]> Table { get { return table; } }
public void Duplicate() { p(); }
}
private static int duplicate;
private static object lck = new object();
public static void Increment()
{
lock(lck)
{
duplicate++;
}
}
public static int GetDuplicate()
{
int res;
lock(lck)
{
res = duplicate;
}
return res;
}
public static void Main(string[] args)
{
List<string> hosts = new List<string>();
hosts.Add("
www.eksperten.dk");
hosts.Add("
www.google.com");
hosts.Add("
www.microsoft.com");
hosts.Add("
www.noexisting.dk");
hosts.Add("
www.google.com");
Dictionary<string, IPAddress[]> table = new Dictionary<string, IPAddress[]>();
ThreadPool.SetMaxThreads(100, 100);
foreach(string host in hosts)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Lookup), new Param(host, table, Increment));
}
while(table.Count + GetDuplicate() < hosts.Count)
{
Thread.Sleep(100);
}
foreach(string host in table.Keys)
{
Console.WriteLine(host + ":");
if(table[host] != null)
{
foreach(IPAddress addr in table[host])
{
Console.WriteLine(" " + addr.ToString());
}
}
else
{
Console.WriteLine(" Unknown");
}
}
Console.ReadKey();
}
public static void Lookup(object info)
{
Param realinfo = (Param)info;
bool already;
lock(realinfo.Table)
{
already = realinfo.Table.ContainsKey(realinfo.Host);
}
if(already)
{
realinfo.Duplicate();
}
else
{
IPAddress[] addr;
try
{
addr = Dns.GetHostEntry(realinfo.Host).AddressList;
}
catch (Exception)
{
addr = null;
}
lock(realinfo.Table)
{
if (realinfo.Table.ContainsKey(realinfo.Host))
{
realinfo.Duplicate();
}
else
{
realinfo.Table.Add(realinfo.Host, addr);
}
}
}
}
}
}