Click here to Skip to main content
15,886,919 members
Please Sign up or sign in to vote.
2.50/5 (2 votes)
See more:
I have a two methods say Method1 and Method2 in a class named ClassB and one more class called ClassA.

From classA Starts:
1.creates one instance of ClassB and classB constuctor invoke the timer(which used to call MethodB for every 10 mins )
2.creates thread to call MethodA for every 10 seconds.

while MethodB is updating (by the invocation of timer),i need to lock MethodA of ClassB.

Since MethodA and MethodB are using same static variables.I want to update settings from MethodB at that time i need to stop processing on MethodA.

Here is my code:
C#
using System;
using System.Threading;

namespace ConsoleApplication1
{
    // ThreadLock.cs
    class ThreadLock
    {
        public static void DoLock()
        {
            Thread[] threads = new Thread[10];
            Account acc = new Account(1000);
            for (int i = 0; i < 10; i++)
            {
                Thread t = new Thread(new ParameterizedThreadStart(acc.DoTransactions));
                threads[i] = t;
            }
            for (int i = 0; i < 10; i++)
            {
                threads[i].Start(i+1);
                Thread.Sleep(1000);
            }
        }
    }

    class Account
    {
        private Object thisLock = new Object();
        private System.Threading.Timer updateBalanceThread = null;
        int balance;

        Random r = new Random();

        public Account(int initial)
        {
            balance = initial;

            //Update balance every 10 sec
            updateBalanceThread = new System.Threading.Timer(new TimerCallback(UpdateBalance), null, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10));

        }

        /// <summary>
        /// Update Balance
        /// Issue:During balance update,i need to wait withdrawal process after update only allow to withdraw
        /// </summary>
        /// &lt;param name="Balance"&gt;&lt;/param&gt;
        public void UpdateBalance(object Balance)
        {
            //when i update balance i need to stop withdrawal
            balance += 1000;
            Thread.Sleep(1000);
        }

        int Withdraw(int amount)
        {

            // This condition will never be true unless the lock statement
            // is commented out:
            if (balance &lt; 0)
            {
                throw new Exception("Negative Balance");
            }

            // Comment out the next line to see the effect of leaving out 
            // the lock keyword:
            lock (thisLock)
            {
              
                if (balance &gt;= amount)
                {
                    Console.WriteLine("Balance before Withdrawal :  " + balance);
                    Console.WriteLine("Amount to Withdraw        : -" + amount);
                    balance = balance - amount;
                    Console.WriteLine("Balance after Withdrawal  :  " + balance);
                    return amount;
                }
                else
                {
                    Console.WriteLine("Balance:" + balance + "---Withdrawal  :  " + amount);
                    return 0; // transaction rejected
                }
            }
        }

        public void DoTransactions(object threadNo)
        {
            //Need lock here

            Console.WriteLine("Threand Number:" + (string)threadNo.ToString());

            for (int i = 0; i &lt; 10; i++)
            {
                Withdraw(r.Next(1, 10));
            }          
        }
    }
}


Anyone solve my problem?
Posted
Updated 24-Mar-11 5:44am
v2
Comments
Olivier Levrey 24-Mar-11 9:08am    
Where is the code? We can't help if you don't show what you tried.
Manivannan Shan 24-Mar-11 9:39am    
[Code moved from this comment to the original question] - Nuri
Nuri Ismail 24-Mar-11 11:49am    
I moved your code from your comment. Please, check out the new version of your question.

You can use a global static variable isLocked as boolean intialized as false.

Class B
{
    B()
    {
       while (!isLocked) {     
            isLocked = true
             MethodB()
            isLocked = false
       }
    }

}

You can use similar procedure where you are calling Method A from Class A. This will prevent methodA and MethodB called simultaneously.
 
Share this answer
 
Comments
Manivannan Shan 24-Mar-11 9:43am    
Vijay i expected as per the code I posted.
see the code,In this During balance update,i need to wait withdrawal process.After updation of balance only allow to withdraw.

For normal withdrawal ,I dont want any lock
Can't you just use lock(this) around the parts you want to be locked? As long as they don't call each other from within the locked part, of course.
 
Share this answer
 
Comments
Rick Shaub 24-Mar-11 11:48am    
Good answer, although you shouldn't use lock(this) because external code can lock on this. Use a readonly object instead and lock on that.
BobJanova 24-Mar-11 12:26pm    
Yes, for a professional solution you are correct, although external code shouldn't use lock on an object unless it intentionally wants to interfere with that object's own synchronisation, in my opinion.

(By the way, the OP's code is an example from MSDN. Further information is available there on advanced locking techniques. He needs to provide more information about what he's actually trying to do, as the lock in his code should be working fine as it stands.)
Use a static object for your lock if you are having problems with a static member.

private static staticLock = new Object();
...

lock(staticLock)
{
    //Access the static members...
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900