2013-07-27 2 views
0

Я работал с кодом C# в течение последних 4 лет, но недавно я прошел через сценарий, который я никогда не проходил. У меня есть проклятый проект по устранению ошибки «Index out of range». Код выглядит сумасшедшим, и все ненужные вещи были там, но он был в производстве в течение последних 3 лет. Мне просто нужно исправить эту проблему. Приходится к проблеме.Проблема синхронизации с синхронизацией в Parallel.Foreach

class FilterCondition 
{ 
    ..... 
    public string DataSetName {get; set;} 
    public bool IsFilterMatch() 
    { 
     //somecode here 
     Dataset dsDataSet = FilterDataSources.GetDataSource(DataSetName); // Static class and Static collection 
     var filter = "columnname filtername" 
     //some code here 
     ds.defaultview.filter= filter; 
     var isvalid = ds.defaultView.rowcount > 0? true : false; 
     return isValid; 
    } 
} 

// from a out side function they put this in a parallel loop 

Parallel.ForEach() 
{ 
    // at some point its calling 
    item.IsFiltermatch(); 
} 

Когда я отладки, dsDataSet я увидел, что dsDataSet модифицируют свои несколько потоков. Вот почему условие гонки происходит, и он не смог применить фильтр и не смог с индексом из диапазона.

Мой вопрос здесь в том, что мой метод нестационарный и потокобезопасный, то как это состояние гонки происходит с dsDataset, является локальной переменной внутри моей функции-члена. Странно, я подозреваю, что это связано с Parallel.Foreach.

И когда я установил нормальный замок, проблема была решена, потому что у меня тоже нет ответа. Почему я должен ставить блокировку на нестационарную функцию-член?

Может ли кто-нибудь дать мне ответ на это. Я новичок в группе. если у меня ничего нет в вопросе, пожалуйста, дайте мне знать. Я не могу скопировать весь код, так как клиентские ограничения там. Спасибо за прочтение.

+0

Проблема заключается в этом вызове FilterDataSources.GetDataSource (DataSetName); вы пишете ресурс, который является общим. И вам нужно реализовать блокировку. – Ehsan

ответ

2

Потому что это не безопасный поток.
Вы получаете доступ к статической коллекции из нескольких потоков.

У вас есть неправильное представление о локальных переменных. Хотя переменная является локальной, она указывает на объект, который не является.

Что вам нужно сделать, это добавить замок вокруг мест, где вы читаете и записываете в статическую коллекцию.

+0

Если я получаю доступ к статическому ресурсу, весь метод потеряет поток safty? как это ?если это со статической коллекцией, как простая блокировка решает проблему? объект блокировки должен быть неподвижным? Даже у меня также есть неправильное представление с локальной переменной. – user2613883

+0

@ user2613883 Безопасность потока не входит в область действия метода. Речь идет о безопасности доступа к одному и тому же ресурсу. Для каждого общего ресурса должна быть единственная блокировка для синхронизации доступа. Так что да, блокировка должна быть также статичной в вашем случае, и каждый поток должен использовать тот же самый замок. –

0

Я считаю, что это связано с конкретной (не-безгосударственной, не потоковой безопасностью и т. Д.) Реализацией FilterDataSources.GetDataSource(DataSetName), даже вызовом метода кажется, что это статический метод. Этот метод может делать разные вещи, даже возвращать кешированный экземпляр DataSet, перехватывать вызовы на элементы набора данных, возвращать обертку DataSet, чтобы вы работали с оберткой, а не с набором данных, поэтому может быть много чего. Если вы хотите точно сказать «точная строка кода», которая вызывает это, пожалуйста, покажите нам реализацию метода GetDataSource() и всего основного статического контекста класса FilterDataSource (статические поля, конструктор, другие статические методы, вызываемые GetDataSource(), если таковые существуют. ..)

+0

Его вытаскивание набора данных из статического словаря, как словарь, так и метод являются статическими. – user2613883

1

проблема: проблема заключается в этом вызове

FilterDataSources.GetDataSource(DataSetName); 

внутри этого метода вы пишете ресурс, который является общим.

Решение:

Вы должны знать, какое поле записывается здесь и нужно реализовать блокировку на нем.

Примечание: Если бы вы могли опубликовать свой код для вышеуказанного метода, мы были бы в лучшем положении, чтобы помочь вам.

Смежные вопросы