Deutsch
Germany.ruФорумы → Архив Досок→ Программирование

Используете уникальные идентификаторы для объектов?

1559  1 2 3 все
alex445 патриот03.11.24 19:48
NEW 03.11.24 19:48 
в ответ NightWatch 03.11.24 16:10, Последний раз изменено 03.11.24 19:52 (alex445)
internal class Program
{
    private static ulong idCounter = 0;

    static void Main(string[] args)
    {
        Task[] tasks = new Task[10];
        for (int j = 0; j < tasks.Length; j++) {
            tasks[j] = Task.Factory.StartNew(Increment);
        }
        Task.WaitAll(tasks);
        Debug.WriteLine($"Counter: {idCounter}");
    }

    private static void Increment()
    {
        for (int i = 0; i < 10000; i++) {
            idCounter++;
        }
    }
}

Да... Да, это не атомарно. Обманули! Пишут будто одну операцию, а сами сокращают i = i + 1.

В этом долбаном Сишарпе даже чтение и присвоение могут не быть атомарными. Короче, всё потенциально многопоточное надо заворачивать в запирания.

#21 
AlexNek патриот03.11.24 19:51
AlexNek
NEW 03.11.24 19:51 
в ответ alex445 02.11.24 17:12
alex445 патриот03.11.24 19:56
03.11.24 19:56 
в ответ AlexNek 03.11.24 19:51, Последний раз изменено 03.11.24 19:57 (alex445)

Спасибо за ссылку.

Но для по-быстрому сгодится и мой метод генерации. Только залочить, если в многопотоке.

#23 
MrSanders коренной житель03.11.24 19:56
NEW 03.11.24 19:56 
в ответ NightWatch 03.11.24 16:10

Ещё немного и придётся Ололёше про volatile, мониторы и lock рассказывать... О сколько ему открытий чудных :)

#24 
alex445 патриот03.11.24 20:03
NEW 03.11.24 20:03 
в ответ AlexNek 03.11.24 19:45
Зачем тогда какие то придурки сделали "Interlocked.Increment(ref сount);"?

А по моей ссылке чел пишет, что лучше использовать локи, и только если они слишком медленные, то ваш метод Interlocked.Increment. Но этот метод не гарантирует 100% потокобезопасность.

#25 
NightWatch коренной житель03.11.24 20:12
NightWatch
NEW 03.11.24 20:12 
в ответ alex445 03.11.24 20:03
Interlocked.Increment

В твоем конкретном примере применение Interlocked.Increment - это самый быстрый и 100%-о потокобезопасный вариант.

#26 
AlexNek патриот03.11.24 20:16
AlexNek
NEW 03.11.24 20:16 
в ответ alex445 03.11.24 20:03
Но этот метод не гарантирует 100% потокобезопасность.

Естественно, МС как обычно врёт: "Increments a specified variable and stores the result, as an atomic operation."

И только крутые чуваки на SO вещают правду спок

#27 
alex445 патриот03.11.24 20:17
NEW 03.11.24 20:17 
в ответ NightWatch 03.11.24 20:12
Interlocked.Increment

В твоем конкретном примере применение Interlocked.Increment - это самый быстрый и 100%-о потокобезопасный вариант.

в моём конкретном случае поиска моей конкретной проблемы подошёл и мой первый способ

про потокобезопасность это я уже потом добавил )))

#28 
alex445 патриот03.11.24 20:18
NEW 03.11.24 20:18 
в ответ AlexNek 03.11.24 20:16, Последний раз изменено 03.11.24 20:19 (alex445)

Ну как бы этот чувак и писал Дотнет. Точнее, руководил его написанием.

#29 
NightWatch коренной житель03.11.24 20:23
NightWatch
NEW 03.11.24 20:23 
в ответ alex445 03.11.24 20:17

А, понятно. Блеснул, так сказать, знаниями некоторых терминов. )))

#30 
AlexNek патриот03.11.24 20:35
AlexNek
NEW 03.11.24 20:35 
в ответ alex445 03.11.24 20:18
Точнее, руководил его написанием.

Поискать все Ваши посты о руководителях? смущ

Может, примерчик скинете, когда получается неправильный результат? Что-то я как-то по-другому понял написанное. спок

#31 
Программист коренной житель04.11.24 08:40
NEW 04.11.24 08:40 
в ответ alex445 01.11.24 16:28, Последний раз изменено 04.11.24 09:06 (Программист)

Переопредели GetHashCode.


А вообще, сравнивать объекты по ссылке - очень странное решение, не понимаю, как такое вообще пропустили через ревью. Никогда не сравнивнивай объекты через "==", вместо этого используй Equals :)

#32 
Срыв покровов патриот04.11.24 08:53
NEW 04.11.24 08:53 
в ответ Программист 04.11.24 08:40

джависты в чате шок

#33 
Программист коренной житель04.11.24 09:07
NEW 04.11.24 09:07 
в ответ Срыв покровов 04.11.24 08:53

Из джавистов тут был только MrSanders улыб

#34 
alex445 патриот04.11.24 20:00
NEW 04.11.24 20:00 
в ответ NightWatch 03.11.24 20:23
А, понятно. Блеснул, так сказать, знаниями некоторых терминов. )))

Я просто процитировал, что он написал. При этом сейчас он уже не руководит, и в Дотнете могли что-то изменить.

#35 
alex445 патриот04.11.24 20:03
NEW 04.11.24 20:03 
в ответ Программист 04.11.24 08:40
А вообще, сравнивать объекты по ссылке - очень странное решение, не понимаю, как такое вообще пропустили через ревью. Никогда не сравнивнивай объекты через "==", вместо этого используй Equals :)

Что за бред? Это где-то написано в доках? Если я сравниваю два объекта, то они же по ссылке сравниваются - т.е. сравнивается, равны ли их ссылки? А Equals и переопределить могут - получу неожиданный результат.


Мне тогда нужно было именно ссылки сравнить... Хотя, оператор == тоже могут переопределить.

#36 
alex445 патриот04.11.24 20:08
NEW 04.11.24 20:08 
в ответ alex445 04.11.24 20:03, Последний раз изменено 04.11.24 20:08 (alex445)

Это всё фигня. Вот у меня сейчас другой вопрос всплыл. Можно сказать философский. Как яйцу опередить курицу? Как сделать так, чтобы при двойном клике не вызывался обработчик одинарного?


Можно щёлкать мышкой (или тапать пальцем) по контролу. При этом есть одинарный клик (последовательность действий: мышь нажали, мышь отпустили), и есть двойной. Клик проходит, когда мышь отпустили на том же объекте, на котором нажали. Вобщем всё стандартно... Пока придумал лишь задерживать обработчик одного клика - если за интервал между кликами, в течении которого клик считается двойным, не пришёл второй клик, то выполняю обработчик одинарного клика. Если этот интервал достаточно маленький, то пользователь может и не заметить. Хотя всё же будет ощущение подтормаживающего интерфейса.

#37 
AlexNek патриот04.11.24 22:57
AlexNek
NEW 04.11.24 22:57 
в ответ alex445 04.11.24 20:08, Последний раз изменено 05.11.24 17:17 (AlexNek)

Кроме как по времени никак не разделить смущ

Вот что предлагает (не будем показывать пальцем кто). В .md формате


To handle a double-click event separately from a single-click event in Blazor, you can use JavaScript interop to control the timing and differentiate between single and double-clicks.

Here's a clean approach using JavaScript to delay the single-click action slightly. If a double-click is detected within a short time, the single-click action will be ignored.

1. **JavaScript Helper**:
   Add a JavaScript function to detect single vs. double clicks. 
   This function uses `setTimeout` to delay the single-click action, which is canceled if a double-click occurs within the delay period.

   ```html
   <script>
       window.clickHandler = {
           singleClickTimeout: null,

           handleClick: function(elementId, singleClickCallback, doubleClickCallback) {
               clearTimeout(this.singleClickTimeout);
               
               // Set up a timeout for single-click
               this.singleClickTimeout = setTimeout(() => {
                   singleClickCallback();
               }, 250); // Delay to allow for double-click detection

               // Detect double-click
               document.getElementById(elementId).ondblclick = () => {
                   clearTimeout(this.singleClickTimeout);
                   doubleClickCallback();
               };
           }
       };
   </script>
   ```

2. **Blazor Component**:
   Set up your component with `@ref` to access the element ID in JavaScript and call the JavaScript function to handle clicks.

   ```razor
   @page "/click-sample"
   <button @ref="clickButton" @onclick="HandleSingleClick">Click me</button>

   @code {
       private ElementReference clickButton;

       protected override async Task OnAfterRenderAsync(bool firstRender)
       {
           if (firstRender)
           {
               await JS.InvokeVoidAsync("clickHandler.handleClick", 
                   clickButton.Id, 
                   DotNetObjectReference.Create(this),
                   nameof(SingleClickAction),
                   nameof(DoubleClickAction)
               );
           }
       }

       [JSInvokable]
       public void SingleClickAction()
       {
           // Logic for single-click action
       }

       [JSInvokable]
       public void DoubleClickAction()
       {
           // Logic for double-click action
       }

       private async Task HandleSingleClick(MouseEventArgs e)
       {
           // Prevent Blazor's default click behavior, handling it in JavaScript instead
       }
   }
   ```

3. **Explanation**:
   - `clickHandler.handleClick` is a JavaScript function that handles click events for the button.
   - `SingleClickAction` and `DoubleClickAction` are Blazor methods decorated with `[JSInvokable]`, making them callable from JavaScript.
   - `HandleSingleClick` is the Blazor click handler, but it's empty here because JavaScript fully handles click detection.

This approach will prevent the single-click handler from triggering when a double-click is detected, keeping the two actions distinct. 
You can adjust the delay for detecting double-clicks by modifying the timeout value in `setTimeout`.
#38 
alex445 патриот05.11.24 00:16
NEW 05.11.24 00:16 
в ответ AlexNek 04.11.24 22:57

Ну так я и сказал, что задержка обработчика одинарного клика пока единственное решение.

По-моему, логически тут ничего не сделать.

Нужно обходить. Пока решил, что заменю двойной клик на удержание нажатия.

У меня двойные клики раз в 10-20 реже одинарных должны быть, так что удержание не должно сильно раздражать пользователя.


Жаль, что ИИ не научили переносить строки вовремя )))

#39 
Программист коренной житель05.11.24 08:38
NEW 05.11.24 08:38 
в ответ alex445 04.11.24 20:03
Что за бред? Это где-то написано в доках? Если я сравниваю два объекта, то они же по ссылке сравниваются - т.е. сравнивается, равны ли их ссылки? А Equals и переопределить могут - получу неожиданный результат.

Вопрос в том, что именно ты хочешь узнать сравнением.

Если твоя цель узнать указывают ли две ссылки на один и тотже объект, то, конечно, сравнивать нужно сслыки.

Если же тебе нужно сравнивать "состояния" двух объектов, то сравнивать нужно исключительно через Equals.


В твоем примере (и в 95-98% реального использования) сравнивать нужно именно состояние. А значит и сравнивать нужно через Equals.


Мне тогда нужно было именно ссылки сравнить...

Очевидно, что нет :) Во всяком случае, твоя коллекция ничего не знает о том, что объекты нельзя пересоздавать :)

#40 
1 2 3 все