views:

74

answers:

1

ok, so I'm writing a duplicate logon "worker" class in C# and I've ran into a bit of a snag. My logic behind it, I thought, was flawless! :(

But, I can't for the life of me figure out why it's triggering on the first occurence rather than on just duplicates :(

namespace Lab.Core.BackgroundWorker {
    using Lab.Core;
    using Lab.Core.Net;

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;

    public class MultiLogon : IWorker {
     private static Hashtable LoggedOnUsers = new Hashtable();
     private Thread _worker = null;
     //private Thread m_UsersUpdate = null;

     public delegate Boolean AddUserToCollectionDelegate(String user, String computer);
     public delegate void ClearCollectionDelegate(String user);
     public delegate Boolean IsUserLoggedInDelegate(String user);

     public Boolean AddUserToCollection(String user, String computer) {
      int retVal = MultiLogon.LoggedOnUsers.Count + 1;
      if (String.IsNullOrEmpty(user) || String.IsNullOrEmpty(computer))
       return false;
      if (!MultiLogon.LoggedOnUsers.ContainsKey(user))
       MultiLogon.LoggedOnUsers.Add(user, computer);

      return (MultiLogon.LoggedOnUsers.Count == retVal);
     }

     public void ClearCollection() {
      if (MultiLogon.LoggedOnUsers.Count > 0)
       MultiLogon.LoggedOnUsers.Clear();
     }

     public Boolean IsUserLoggedIn(String user) {
      if (String.IsNullOrEmpty(user))
       return false;
      return (LoggedOnUsers.Contains(user));
     }

     #region IWorker Members

     public void Run(object obj) {
      AddUserToCollectionDelegate add = new AddUserToCollectionDelegate(AddUserToCollection);
      //ClearCollectionDelegate clear = new ClearCollectionDelegate(ClearCollection);
      //IsUserLoggedInDelegate isLogged = new IsUserLoggedInDelegate(IsUserLoggedIn);

      while (true) {
       foreach (Computer c in ComputerList.Instance)
        if (!add.Invoke(c.UserName, c.MachineName)) {
         // duplicate! or not? :/
         // Credit (through adoption of code) goes to:
         // http://bytes.com/groups/net-c/263778-quickly-finding-duplicates-arraylist#post1059834
         foreach (DictionaryEntry item in MultiLogon.LoggedOnUsers) {
          MessageBox.Show((String)item.Key, (String)item.Value);
          //NetworkMessage.Send((String)item.Value, String.Format("It is against lab policy to share your account with anyone other than yourself or use someone else's account! Logout immediately or further action will be taken. Your action has been logged."));
          //OffenseManager.Instance.AddOffense((String)item.Key, null, String.Format("Account sharing - Computer: {0}", item.Value), false);
         }
        }
       Thread.Sleep(750);
      }
     }

     public void Start() {
      _worker = new Thread(new ParameterizedThreadStart(Run));
      _worker.IsBackground = true;
      _worker.Start();
     }

     public void Stop() {
      if (_worker.IsAlive)
       _worker.Abort();
     }

     #endregion
    }
}

Apologies for the long code file. I don't know exactly what to paste to help you guys help me. :/

Thanks in advance! :)

A: 

Could be a thread race condition.
Have you tried to lock the collection when you're searching/inserting into it?
I don't believe Hashtable are threadsafe.

You might want to put a

lock(this) {
}

block around anything accessing the hashtable.

Andrew Arace
I invoke to add to the hash table because it's declared on the main thread of the program.
Zack