0
ObservableCollection<MyClass> collection = new ObservableCollection<MyClass>();
public MainWindow()
{
    InitializeComponent();
    collection.Add(new MyClass() { Name = "Vikram" });
    collection.Add(new MyClass() { Name = "Test" });          

    CallingTaskDelay();          
    MyClass class1 = collection[0];
    lock (class1)
    {
        txtName.Text = class1.Name;
    }
}

private Task TaskDelayMethod()
{           
    return Task.Run(() => ChangeItem());
}

private async void CallingTaskDelay()
{
    await TaskDelayMethod();
}

private void ChangeItem()
{
    MyClass myclass = collection[0];
    lock (myclass)
    {
        myclass.Name = "anup";
        Thread.Sleep(5000);
    }
}

While I am changing the content of the instance of the myclass in ChangeItem() method. I want to prevent access of the same instance in the MainWindow() method which I am doing as below -

lock (class1)
{
     txtName.Text = class1.Name;
}

How it can be accomplished. Mine is not working.

Christoph Fink
  • 22,727
  • 9
  • 68
  • 113
Vikram
  • 1,617
  • 5
  • 17
  • 37
  • Explain *Mine is not working* – Sriram Sakthivel May 22 '14 at 06:17
  • @SriramSakthivel the scenario which I have shown..it is not working here – Vikram May 22 '14 at 06:18
  • Not working can have any meaning. Doesn't compile? Exception? Gives unexpected output? If so what ? Please explain. We can't guess – Sriram Sakthivel May 22 '14 at 06:19
  • @SriramSakthivel : it means that, the case which I want is that as long as ChangeItem() is changing the content to "anup", I should not be able to access class1.Name in the MainMethod(). I hope you got what I want. Thanks :) – Vikram May 22 '14 at 06:22
  • 1
    @Vikram [locking on the same object you are going to access is considered a bad practice](http://stackoverflow.com/questions/11775205/why-is-it-a-bad-practice-to-lock-the-object-we-are-going-to-change) – Vamsi May 22 '14 at 06:32

3 Answers3

0

Usually it is better to have a private object to use as a lock, but what you are doing should work as long as MyClass is a reference type. I think the code in your constructor executes before ChangeItem starts and hence you are not seeing any contention. try putting a Thread.Sleep(1000) after CallingTaskDelay().

NeddySpaghetti
  • 13,187
  • 5
  • 32
  • 61
0

I guess you have a "Race condition". ChangeItem is probably not called yet when you acquire lock (class1) in constructor. Otherwise your code should work as expected.

You can check it by adding some sleep.

CallingTaskDelay();
Thread.Sleep(100);//For debugging, just give some time for  `CallingTaskDelay` to call `ChangeItem`
MyClass class1 = collection[0];
lock (class1)
{
    txtName.Text = class1.Name;
}
Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
0

Are you expecting the ChangeItem() method to be run before the Constructor completes? Using the async keyword instructs the compiler to wait until it has nothing else to do before starting it. In the given scenario the ChangeItem() method will always be called After the Constructor completes

martijn
  • 1,417
  • 1
  • 16
  • 26