我是字典的新手,发现它们非常有用。我有一个c#服务器控制台,它接受多个客户端连接。每次客户端连接时,都会将其添加到服务器字典中。我目前正在使用.net 3.5(并且不会很快升级)并且使用的是非线程安全且不是静态的字典。客户端通常会自行退出,但我需要实现故障安全。如果客户端不自行退出,我想在5分钟后使用计时器关闭连接。关闭连接后,需要从字典中删除该项。我如何让我的字典和计时器工作来实现这一目标?我被困住了,耗尽了我的资源。 我使用“_clientSockets.Remove(current)”来关闭连接
下面是我目前对字典和计时器的代码片段:
private static Timer aTimer = new System.Timers.Timer(10000);
private static Object thisLock = new Object();
public static void Main()
{
Console.ReadKey();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 1000 * 60 * 5;
aTimer.Enabled = true;
Console.WriteLine("Press the Enter key to exit the program.");
Console.WriteLine(DateTime.Now);
Console.ReadLine();
Dictionary<int, DateTime> ServDict = new Dictionary<int, DateTime>();
ServDict.Add(9090, DateTime.Now.AddMinutes(5));
ServDict.Add(9091, DateTime.Now.AddMinutes(5));
ServDict.Add(9092, DateTime.Now.AddMinutes(5));
ServDict.Add(9093, DateTime.Now.AddMinutes(5));
ServDict.Add(9094, DateTime.Now.AddMinutes(5));
Console.WriteLine("Time List");
foreach (KeyValuePair<int, DateTime> time in ServDict)
{
Console.WriteLine("Port = {0}, Time in 5 = {1}",
time.Key, time.Value);
}
Console.ReadKey();
}
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
Console.WriteLine("The trigger worked, The Elapsed event was raised at {0}", e.SignalTime);
Console.WriteLine(DateTime.Now);
}
答案 0 :(得分:0)
使用您的方法,无法将字典中的特定键与特定超时相关联。你必须每隔n秒“轮询”你的字典(其中n是你可以错过5分钟标记的数量)并检查你收到数据后的时间长度。
更好的解决方案可能是将您的客户端包装在一个类中(只需保存一个列表,您甚至可能不需要字典)?在这种情况下,类的每个实例都可以保存5分钟后经过的“超时”计时器并调用关闭连接功能。相同的事件处理程序也可以引发一个事件,该类包含所有客户端注册,以便它可以从活动列表中删除它。
每当收到数据时,客户端类都会重置计时器。这可以通过使用System.Threading.Timer并在其上调用Change(dueTime,period)轻松实现。
以下内容应该有效:
public class Client
{
public event Action<Client> Timeout;
System.Threading.Timer timeoutTimer;
public Client()
{
timeoutTimer = new Timer(timeoutHandler, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5));
}
public void onDataRecieved()
{
timeoutTimer.Change(TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5));
}
public void timeoutHandler(object data)
{
CloseConnection();
if (Timeout != null)
Timeout(this);
}
}
class Program
{
List<Client> connectedClients = new List<Client>
void OnConnected(object clientData)
{
Client newClient = new Client();
newClient.Timeout += ClientTimedOut;
connectedClients.Add(newClient);
}
void ClientTimedOut(Client sender)
{
connectedClients.Remove(sender);
}
}