Conflicts of flows in some cases, in a cycle

I am working on a project that uses Threads. In some cases, I have the following problems:

Here is part of my code:

List<EmailAddress> lstEmailAddress = new List<EmailAddress>();
private void TimerCheckInternetConnection_Tick(object sender, EventArgs e)
{
    lock (TicketLock)
    {
        if (UtilityManager.CheckForInternetConnection())
        {
            if (ApplicationRunStatus == Enum_ApplicationRunStatus.UnknownDisconnect || ApplicationRunStatus == Enum_ApplicationRunStatus.IsReady)
            {
                // Connect
                ThreadPool.QueueUserWorkItem((o) =>
                {
                    for (int i = 0; i < lstEmailAddress.Count; i++)
                    {
                        lstEmailAddress[i].IsActive = lstEmailAddress[i].Login();
                    }

                    this.BeginInvoke(new Action(() =>
                    {
                        // some code

                    }));
                });
            }
        }
    }
}

and this is the EmailAddress class:

class EmailAddress
{
    private Imap4Client imap = new Imap4Client();
    private object objectLock = new object();

    public bool IsActive;
    public string Address;
    public string Password;

    public string RecieveServerAddress;
    public int RecieveServerPort;

    public bool Login()
    {
        lock (objectLock)
        {
            try
            {
                imap.ConnectSsl(RecieveServerAddress, RecieveServerPort);
            }
            catch (Exception)
            {
            }

            try
            {
                imap.Login(Address, Password);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

    }
}

And my problem is this:

When I want to use a procedure Loginrelated to a class EmailAddress, it has a conflict. As you can see, I used Lock, but everything has changed.

More:
If I have 3 elements in lstEmailAddress, the login procedure should be called 3 times with this code. but each time the login procedure will work with the same username and password. Therefore, all my letters cannot log into the system correctly. If I remove threadpool, it will be ok.

+4
2

:

  • lock , , , .
  • QueueUserWorkItem - , TicketLock
  • .
  • i, , , .
  • lock Email static, .
  • Invoke, , . TPL code ThreadPool

:

List<EmailAddress> lstEmailAddress = new List<EmailAddress>();
private void TimerCheckInternetConnection_Tick(object sender, EventArgs e)
{
    // remove this lock as we have another in Email class
    //lock (TicketLock)
    if (UtilityManager.CheckForInternetConnection())
    {
        if (ApplicationRunStatus == Enum_ApplicationRunStatus.UnknownDisconnect
          || ApplicationRunStatus == Enum_ApplicationRunStatus.IsReady)
        {
            for (int i = 0; i < lstEmailAddress.Count; i++)
            {
                // use local variable to store index
                int localIndex = i;
                // Connect
                ThreadPool.QueueUserWorkItem((o) =>
                {
                    // if you add a lock here, this will run synchroniosly,
                    // and you aren't really need the ThreadPool
                    //lock (TicketLock)
                    lstEmailAddress[localIndex].IsActive = lstEmailAddress[localIndex].Login();

                    this.BeginInvoke(new Action(() =>
                    {
                        // some code
                    }));
                });
            }
        }
    }
}

class EmailAddress
{
    // if you have to login only for one user simultaneosly
    // use static variables here, other wise simply remove the lock as it is useless
    private static Imap4Client imap;

    private static object objectLock;
    // static constructor for only one initialization for a static fields
    static EmailAddress()
    {
        objectLock = new object();
        imap = new Imap4Client();
    }

    public bool IsActive;
    public string Address;
    public string Password;

    public string RecieveServerAddress;
    public int RecieveServerPort;

    public bool Login()
    {
        // aquire a static lock
        lock (objectLock)
        {
            try
            {
                imap.ConnectSsl(RecieveServerAddress, RecieveServerPort);
            }
            catch (Exception)
            {
                // STORE THE EXCEPTION!!!
                // return as you haven't connected
                return false;
            }

            try
            {
                imap.Login(Address, Password);
                return true;
            }
            catch (Exception)
            {
                // STORE THE EXCEPTION!!!
                return false;
            }
        }

    }
}
+2

. query lstEmailAddress, . , threadpool. . .

   for (int i = 0; i < lstEmailAddress.Count; i++)
     { 
    ThreadPool.QueueUserWorkItem((o) =>
                         {
                            lstEmailAddress[i].IsActive = lstEmailAddress[i].Login();
                         }   
    }
-4

All Articles