锁定数据对象的最佳做法

时间:2017-02-16 09:10:09

标签: c# multithreading locking task

我写了一个处理大文本文件的应用程序。在内部,文本文件存储为DataObject,其中包含多个数据,如文件行,文件路径等。我可以用应用程序修改这些文件(分别是数据对象)。因为某些方法非常耗时,所以我在Task中运行它们以避免阻塞UI。现在,使用非阻塞UI,我想确保用户不会尝试修改当前正在Task中处理的文件,因此我想锁定DataObject。为此,我认为我可以向DataObject类添加一个锁对象。然后我会以这种方式锁定DataObject:

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
        }
    }));
}

这是要走的路吗?或者有更好的方法吗?

1 个答案:

答案 0 :(得分:4)

从不公开 LockObject,隐藏实施细节:

private object m_LockObject = new object();

下一期:为什么timeConsumingMethod收到DataObject而不是DataObjectpublic class DataObject { // locking object is a private implementation detail private object m_LockObject = new object(); // TheMethod works with "this" DataObject instance, that's why // the method belongs to DataObject // let's return Task (e.g. to await it) // Think on method's 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();  

   ...
 }

然后只需调用方法

tableview cell