Best practices for locking data objects

I wrote an application that processes large text files. Internally, the text file is stored as a DataObject that contains several data, such as the lines of the file, the path to the file, etc. I can modify these files (data object accordingly) using the application. Since some methods are time consuming, I run them in Task to avoid blocking the user interface. Now, with a non-blocking user interface, I want to make sure that the user is not trying to modify the file that is currently being processed in the Task, so I want to block the DataObject. To do this, I decided to add a lock object to the DataObject class. Then I blocked DataObject as follows:

public class DataObject {
    public object LockObject = new object();
    // ...

    public DataObject() { }
}

public void timeConsumingMethod(DataObject data) {
    Task.Factory.StartNew(new Action(() => {
        lock(data.LockObject) {
            // do work
        }
    }));
}

Is that the way? Or is there a better way?

+4
1

LockObject, :

private object m_LockObject = new object();

: timeConsumingMethod DataObject , DataObject:

public class DataObject {
  // locking object is a private implementation detail
  private object m_LockObject = new object();

  // TheMethod works with "this" DataObject instance, that why
  // the method belongs to DataObject
  // let return Task (e.g. to await it)
  // Think on method name; 
  public Task TheMethodAsync() {
    // Task.Factory.StartNew is evil
    return Task.Run(() => {
      lock (m_LockObject) {
        // ...
      } 
    });
  }

  ...
}

 public void timeConsumingMethod(DataObject data) {
   // When designing public methods do not forget about validation
   if (null == data)
     throw new ArgumentNullException("data");

   // Think on awaiting the Task returned:
   // "i run them in a Taks ... to avoid blocking the UI"
   // await data.TheMethodAsync();  
   data.TheMethodAsync();  

   ...
 }
+4

Source: https://habr.com/ru/post/1669907/


All Articles