Как пометить метод как не-безопасный? - PullRequest
0 голосов
/ 04 марта 2020

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

private readonly object _syncRoot = new object();

private List<int> NonconcurrentObject { get; } = new List<int>();

public void Fiddle()
{
    lock (_syncRoot)
    {
        // ...some code...
        NonconcurrentObject.Add(1);
        Iddle();
    }
}

public void Twiddle()
{
    lock (_syncRoot)
    {
        // ...some different code...
        NonconcurrentObject.Add(2);
        Iddle();
    }
}

private void Iddle()
{
    // NOT THREADSAFE! DO NOT CALL THIS WITHOUT LOCKING ON _syncRoot
    // ......lots of code......
    NonconcurrentObject.Add(3);
}

У меня есть несколько опубликованных c методов класса с некоторым кодом, который по своей природе не является Безопасный поток (List выше - тривиальный пример). Я хочу использовать вспомогательные методы для кода, разделяемого между ними (как и любой другой), но при разделении общего кода я сталкиваюсь с дилеммой: использовать ли рекурсивную блокировку в вспомогательных методах или нет? Если я это сделаю, мой код будет расточительным и, возможно, менее производительным. Если я этого не сделаю (как указано выше), вспомогательный метод больше не является потокобезопасным и открыт для неприятных условий гонки, если в будущем его вызовет какой-то другой метод.

Как я могу (элегантно и надежно) сигнализировать, что метод не безопасен для потоков?

Ответы [ 3 ]

3 голосов
/ 04 марта 2020

Вы используете c комментарии.

///<remarks>not thread safe</remarks>
0 голосов
/ 04 марта 2020

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

Преимущества: Это напоминает вам, что вы делаете опасные вещи, и поэтому вы должен быть очень осторожным. Небольшая ошибка может стоить вам дней отладки в будущем.

Недостатки: Не очень красиво, и его можно спутать с ключевым словом unsafe.

private void Iddle_Unsafe()
{
    NonconcurrentObject.Add(3);
}

public void Twiddle()
{
    lock (_syncRoot)
    {
        NonconcurrentObject.Add(2);
        Iddle_Unsafe();
    }
}
0 голосов
/ 04 марта 2020

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

Преимущество перед комментариями состоит в том, что он дает вам возможности для дальнейшей обработки (через рефлексию), если вы захотите сделать это позже.

public class NotThreadSafe : Attribute
{
    //...
}

public class MyClass
{
    [NotThreadSafe]
    public void MyMethod()
    {
        //...
    }
}
...