RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题

全部问题

Martin Hope
D .Stark
Asked: 2024-11-16 23:31:09 +0000 UTC

具有异步等待更改功能的 C# 线程安全字典

  • 6

任务是创建一个线程安全的字典,允许您异步等待键更新值。此外,如果在值中使用特殊集合,则会跟踪集合本身内的更改。如果在用户调用等待更新方法之前添加或更新了值,它将立即返回。如何优化该字典以使其在高负载环境中工作?我将很高兴收到任何改进建议(包括那些与性能改进无关的建议)。

public enum CollectionChangedAction {
    ItemAdded, 
    ItemRemoved, 
    ItemUpdated,
    Reset
}

public class CollectionChangedEventArgs : EventArgs {

    public CollectionChangedAction Action { get; private set; }

    public CollectionChangedEventArgs(CollectionChangedAction action) => Action = action;
}

public interface IObservableCollection {
    public event EventHandler<CollectionChangedEventArgs> CollectionChanged;
}

public class AsyncDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>> {

    private class DefaultEqualityComparer<T> : IEqualityComparer<T> {
        public static DefaultEqualityComparer<T> Instance { get; } = new DefaultEqualityComparer<T>();
        private DefaultEqualityComparer() { }

        public bool Equals(T x, T y) {
            if (default(T) == null) return ReferenceEquals(x, y);
            return EqualityComparer<T>.Default.Equals(x, y);
        }

        public int GetHashCode(T obj) {
            if (default(T) == null)
                return obj != null ? RuntimeHelpers.GetHashCode(obj) : 0;
            return EqualityComparer<T>.Default.GetHashCode(obj);
        }
    }

    /// <summary>
    /// Управляет подпиской на события изменения коллекции.
    /// </summary>
    private class CollectionChangedHandlerController {

        private EventHandler<CollectionChangedEventArgs> EventHandler;

        /// <summary>
        /// Подключенная наблюдаемая коллекция.
        /// </summary>
        public IObservableCollection Collection { get; private set; }

        public CollectionChangedHandlerController(IObservableCollection collection) {
            Collection = collection;
        }

        public void AddHandler(EventHandler<CollectionChangedEventArgs> eventHandler) {
            if (eventHandler == null)
                throw new ArgumentNullException(nameof(eventHandler));
            if (EventHandler != null)
                throw new InvalidOperationException("Обработчик уже зарегистрирован для данного события.");

            if (Collection != null) {
                EventHandler = eventHandler;
                Collection.CollectionChanged += eventHandler;
            }
        }

        public void RemoveHandler() {
            if (EventHandler != null) {
                Collection.CollectionChanged -= EventHandler;
                EventHandler = null;
            }
        }
    }

    private readonly bool IsObservableCollectionInValue;
    private readonly ConcurrentDictionary<TKey, TValue> InnerDictionary;
    private readonly ConcurrentDictionary<TKey, CollectionChangedHandlerController> InnerCollectionsDictionary;
    private readonly ConcurrentDictionary<TKey, TaskCompletionSource> Awaiters = new();
    private readonly IEqualityComparer<TValue> ValueEqualityComparer = DefaultEqualityComparer<TValue>.Instance;

    public int Count => IsObservableCollectionInValue ? InnerCollectionsDictionary.Count : InnerDictionary.Count;

    public bool IsEmpty => IsObservableCollectionInValue ? InnerCollectionsDictionary.IsEmpty : InnerDictionary.IsEmpty;

    /// <summary>
    /// Типы отслеживаемых изменений коллекции.
    /// </summary>
    public CollectionChangedAction[] TrackedChangeActions { get; private set; }

    public AsyncDictionary() {
        IsObservableCollectionInValue = typeof(TValue).IsAssignableTo(typeof(IObservableCollection));
        if (!IsObservableCollectionInValue) InnerDictionary = new();
        else {
            InnerCollectionsDictionary = new();
            TrackedChangeActions = [
                CollectionChangedAction.ItemAdded,
                CollectionChangedAction.ItemRemoved,
                CollectionChangedAction.ItemUpdated,
                CollectionChangedAction.Reset];
        }
    }

    /// <summary>
    /// Инициализирует новый экземпляр класса <see cref="AsyncDictionary{TKey, TValue}"/>, 
    /// задавая отслеживаемые типы изменений коллекции.
    /// </summary>
    /// <param name="trackedChangeActions">
    /// Массив отслеживаемых типов изменений, происходящих в коллекции.
    /// </param>
    public AsyncDictionary(CollectionChangedAction[] trackedChangeActions) : this() {
        if (trackedChangeActions == null)
            throw new ArgumentNullException(nameof(trackedChangeActions));
        if (!IsObservableCollectionInValue)
            throw new NotSupportedException("Отслеживание изменений поддерживается только для значений, реализующих интерфейс IObservableCollection.");

        TrackedChangeActions = trackedChangeActions.Distinct().ToArray();
    }

    /// <summary>
    /// Инициализирует новый экземпляр класса <see cref="AsyncDictionary{TKey, TValue}"/>, 
    /// копируя элементы из указанного словаря.
    /// </summary>
    /// <param name="valueEqualityComparer">
    /// Необязательный компаратор значений для определения необходимости уведомлений об обновлениях. 
    /// Если не указан, используется компаратор по умолчанию.
    /// </param>
    public AsyncDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TValue> valueEqualityComparer = null) : this() {
        if (dictionary == null)
            throw new ArgumentNullException(nameof(dictionary));

        InnerDictionary = new ConcurrentDictionary<TKey, TValue>(dictionary);
        foreach (var key in dictionary.Keys) {
            var completionSource = new TaskCompletionSource();
            completionSource.SetResult();
            Awaiters.TryAdd(key, completionSource);
        }

        if (valueEqualityComparer != null)
            ValueEqualityComparer = valueEqualityComparer;
    }

    /// <summary>
    /// Добавляет новый элемент или обновляет существующий элемент в словаре.
    /// </summary>
    public void AddOrUpdate(TKey key, TValue value) {
        if (IsObservableCollectionInValue) {
            void onCollectionChanged(object sender, CollectionChangedEventArgs e) {
                if (TrackedChangeActions.Contains(e.Action) &&
                    Awaiters.TryGetValue(key, out var completionSource) &&
                    !completionSource.Task.IsCompleted) {
                    completionSource.SetResult();
                }
            };

            var newValue = new CollectionChangedHandlerController((IObservableCollection)value);
            newValue.AddHandler(onCollectionChanged);
            InnerCollectionsDictionary.AddOrUpdate(key, newValue, (key, existingValue) => {
                existingValue.RemoveHandler();
                return newValue;
            });
        } else {
            bool newValueProduced = true;
            InnerDictionary.AddOrUpdate(key, value, (key, existingValue) => {
                newValueProduced = !ValueEqualityComparer.Equals(value, existingValue);
                return value;
            });

            if (newValueProduced)
                Awaiters.GetOrAdd(key, _ => new TaskCompletionSource()).TrySetResult();
        }
    }

    /// <summary>
    /// Пытается получить значение из словаря по ключу.
    /// </summary>
    public bool TryGetValue(TKey key, out TValue value) {
        if (IsObservableCollectionInValue) {
            if (InnerCollectionsDictionary.TryGetValue(key, out var handlerController)) {
                value = (TValue)handlerController.Collection;
                return true;
            }
            value = default;
            return false;
        } else {
            return InnerDictionary.TryGetValue(key, out value);
        }
    }

    /// <summary>
    /// Пытается удалить элемент из словаря по ключу.
    /// </summary>
    public bool TryRemove(TKey key) {
        if (IsObservableCollectionInValue) {
            if (!InnerCollectionsDictionary.TryRemove(key, out var handlerController))
                return false;
            handlerController.RemoveHandler();
        } else if (!InnerDictionary.TryRemove(key, out _)) {
            return false;
        }

        if (Awaiters.TryRemove(key, out var completionSource))
            completionSource.TrySetCanceled();
        return true;
    }

    /// <summary>
    /// Очищает словарь, удаляя все элементы.
    /// </summary>
    public void Clear() {
        if (IsObservableCollectionInValue) {
            var handlerControllers = InnerCollectionsDictionary.Values.ToArray();
            InnerCollectionsDictionary.Clear();
            foreach (var handlerController in handlerControllers)
                handlerController.RemoveHandler();
        } else {
            InnerDictionary.Clear();
        }

        var completionSources = Awaiters.Values.ToArray();
        Awaiters.Clear();
        foreach (var completionSource in completionSources)
            completionSource.TrySetCanceled();
    }

    /// <summary>
    /// Асинхронно ожидает изменения значения для указанного ключа.
    /// </summary>
    /// <param name="key">Ключ отслеживаемого значения.</param>
    /// <param name="cancellationToken">Токен отмены операции.</param>
    /// <returns>Обновлённое значение, связанное с указанным ключом.</returns>
    public async ValueTask<TValue> WaitForUpdate(TKey key, CancellationToken cancellationToken) {
        var completionSource = Awaiters.GetOrAdd(key, _ => new TaskCompletionSource());
        await completionSource.Task.WaitAsync(cancellationToken);

        Awaiters.TryUpdate(key, new TaskCompletionSource(), completionSource);

        TValue value;
        if (IsObservableCollectionInValue) {
            if (!InnerCollectionsDictionary.TryGetValue(key, out var handlerController))
                throw new OperationCanceledException();
            value = (TValue)handlerController.Collection;
        } else {
            if (!InnerDictionary.TryGetValue(key, out value))
                throw new OperationCanceledException();
        }

        return value;
    }

    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() {
        if (IsObservableCollectionInValue) {
            return InnerCollectionsDictionary.ToDictionary(pair => pair.Key,
                pair => (TValue)pair.Value.Collection).GetEnumerator();
        }

        return InnerDictionary.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
c#
  • 1 个回答
  • 54 Views
Martin Hope
Гусь TV
Asked: 2024-11-16 23:01:55 +0000 UTC

4 个变量计算器 Puthon TG BOT

  • 6

请告诉我为什么函数5没有执行以及我是否正确分配了全局变量?

def num1_fun(message):
    bot.send_message(message.chat.id, 'Введите оклад по званию:⭐')
    bot.register_next_step_handler(message, num1_fun)
    
def num1_fun(message):
    global num1;
    num1 = num1_fun
    if message.text.isdigit():  
        salary = int(message.text)
        if 7000 <= salary <= 35000:  
            bot.send_message(message.chat.id, f'Пойдет ✅ {salary}')
            bot.send_message(message.chat.id, 'Введите оклад по должности:👮')
            bot.register_next_step_handler(message, num2_fun)
            return
        else:
            bot.send_message(message.chat.id, 'Укажите верный оклад 🐒')
    else:
        bot.send_message(message.chat.id, 'Оклад должен быть числом 🐒')
    
    bot.register_next_step_handler(message, num1_fun)
    
    
def num2_fun(message):
    global num2;
    num2 = num2_fun
    if message.text.isdigit():  
        salary = int(message.text)
        if 15000 <= salary <= 45000:  
            bot.send_message(message.chat.id, f'Пойдет ✅ {salary}')
            bot.send_message(message.chat.id, 'Ведите процентную надбавку за выслугу лет к окладам денежного содержания в процентах:📅')
            bot.register_next_step_handler(message, num3_fun)
            return
        else:
            bot.send_message(message.chat.id, 'Укажите верный оклад 🐒')
    else:
        bot.send_message(message.chat.id, 'Оклад должен быть числом 🐒')
    
    bot.register_next_step_handler(message, num2_fun)
    
def num3_fun(message):
    global num3;
    num3 = num3_fun
    if message.text.isdigit():  
        salary = int(message.text)
        if 1000 <= salary <= 4000:  
            bot.send_message(message.chat.id, f'Пойдет ✅ {salary}')
            bot.send_message(message.chat.id, 'Размер пенсии в зависимости от выслуги лет в процентах:💵')
            bot.register_next_step_handler(message, num4_fun)
            return
        else:
            bot.send_message(message.chat.id, 'Укажите верный оклад 🐒')
    else:
        bot.send_message(message.chat.id, 'Оклад должен быть числом 🐒')
    
    bot.register_next_step_handler(message, num3_fun)
    
def num4_fun(message):
    global num4;
    num4 = num4_fun
    if message.text.isdigit():  
        salary = int(message.text)
        if 100 <= salary <= 400:  
            bot.send_message(message.chat.id, f'Пойдет ✅ {salary}')
            bot.register_next_step_handler(message, num5_fun)
            return
        else:
            bot.send_message(message.chat.id, 'Укажите верный оклад 🐒')
    else:
        bot.send_message(message.chat.id, 'Оклад должен быть числом 🐒')
    
    bot.register_next_step_handler(message, num4_fun)
    
def num5_fun(message):
    A = num1 + num2
    B = A * int(num3) / 100
    X = A + B
    C = X * 0.8932
    B = C * int(num4) / 100
    bot.send_message(message.chat.id,B)
    bot.send_message(message.chat.id,"Повторить💸 /start")
python
  • 1 个回答
  • 46 Views
Martin Hope
overxffff
Asked: 2024-11-16 22:48:25 +0000 UTC

挂载磁盘镜像

  • 5

我有一个磁盘映像,已收到ddrescue /dev/sda image.img mapfile,它有三个分区 sda1、sda2、sda3,我如何挂载它以获得必要的文件?文件系统 sda3 - NTFS、sda1、sda2 是服务,不需要它们。

linux
  • 1 个回答
  • 33 Views
Martin Hope
pythonniy_chainik
Asked: 2024-11-16 22:42:19 +0000 UTC

Python,如何在没有循环的情况下将矩阵连接到列表中?

  • 10

例如,有一个矩阵

 [['1', '4', '9', '9', '4', '7'], ['6', '9', '8', '6', '7', '4'],
 ['1', '1', '6', '1', '1', '1'], ['1', '4', '5', '8', '7', '5'],
 ['6', '7', '8', '1', '1', '0'], ['6', '9', '9', '9', '7', '7']]

如何将这个矩阵连接到一个lst=[]没有循环的列表中?列一个清单lst=['1', '4', '9', '9', '4', '7','6', '9', '8', '6', '7', '4','1', '1', '6', '1', '1', '1','1', '4', '5', '8', '7', '5','6', '7', '8', '1', '1', '0', '6', '9', '9', '9', '7', '7']?

python
  • 4 个回答
  • 50 Views
Martin Hope
Nevskiy
Asked: 2024-11-16 22:30:38 +0000 UTC

如何使用 QLineEdit 中的数据更新 QLabel?

  • 6

如何在 中输入数字后QLineEdit,将该数字插入到 中QLabel,并在输出之前QLabel将该数字与值相加10?
例如输入QLineEdit- 5,QLabel输出 - 15。

主要.py:

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton, QLabel, QVBoxLayout, QLineEdit)

class MyWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.my_label = QLabel()
        self.line_edit = QLineEdit()
        self.layout = QVBoxLayout()
        self.layout.addWidget(self.my_label)
        self.layout.addWidget(self.line_edit)
        self.setLayout(self.layout)
        self.line_edit.textChanged.connect(self.magic)

    def magic(self):
        self.A = 10
        self.my_label.setText(self.line_edit.text())

if __name__ == "__main__":
    app = QApplication(sys.argv)
    widget = MyWidget()
    widget.resize(200, 150)
    widget.show()
    sys.exit(app.exec())
python
  • 1 个回答
  • 21 Views
上一页
下一页

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5