Вопрос по c# – Потокобезопасный DataSet

0

Я хочу сделать операции обновления поточно-ориентированными для DataTable / DataSet. Существует ~ 20 потоков, каждое из которых обновляет ~ 40 строк глобальной таблицы данных, используяRows.Find(pk) метод DataTable. Каждый поток будет обновлять отдельные строки DataTable.

Я использую следующий класс-оболочку для DataSet. Является ли этот подход потокобезопасным?

<code>public sealed class MyDataSet{

    public static DataSet ds = new DataSet();

    public static UpdateRow(key,data)
    {
        object _lock = new object();
        DataRow dr = ds.Tables[0].Rows.Find(key);
        lock(_lock){          
            dr.AcceptChanges();
            dr.BeginEdit();
            dr["col"] = data;
            dr.EndEdit();
        }
    }
}
</code>

Этот метод вызывается изfor петля.

<code>for(int x=0; x<40; x++;){
    if(someCondition)
    .
    .
    .
    MyDataSet.UpdateRow(key,data);
    .
    .
    .
    }
</code>

Все сделано в многопоточной среде. Безопасен ли метод UpdateRow?

Ваш Ответ

2   ответа
1

Is UpdateRow method thread safe?

Нет, это не так. Вы создаете блокировку наnew object каждый раз, когда вы вводите метод. Объект, для которого вы блокируете, должен быть одинаковым во всех потоках, иначе блокировка никогда не будет считаться "взятой" так как каждый поток успешно создает новую блокировку для объекта, который он выбрасывает впоследствии. Один из способов добиться этого - сделать объект, который вы блокируете, статичным.

5

Нет, это не безопасно. Вы должны изменить свой код в:

public sealed class MyDataSet{

    public static DataSet ds = new DataSet();

    private static object _lock = new object();

    public static UpdateRow(key,data)
    {
        lock(_lock){
            DataRow dr = ds.Tables[0].Rows.Find(key);
            dr.AcceptChanges();
            dr.BeginEdit();
            dr["col"] = data;
            dr.EndEdit();
        }
    }
}

Ваш_lock объект должен быть статическим объектом в вашей программе, чтобы сделать его хорошей блокировкой. И вашFind должен быть в запертой части.

Похожие вопросы