Ответы пользователя по тегу C#
  • Почему потоки накапливаются и не уничтожаются?

    @none7
    Принудительную сборку мусора через GC.Collect() пробовали применять? Если не помогает, значит, где-то остались ссылки и есть утечка памяти, иначе Dispose вызывается не везде в Вашем коде.
    Ответ написан
    Комментировать
  • В чём отличие многопоточности и асинхронности в контексте .NET C#?

    @none7
    Разница в том, что многопоточность это вытесняющая многозадачность, а async это кооперативная. А блокируймость и неблокируймость это из религии JS пришло, где потоков нет вообще. У обоих подходов есть как свои плюсы, так и свои минусы.
    Ответ написан
    Комментировать
  • Как устанавливается head.Next при добавлении элемента в односвязном списке?

    @none7
    С чего вдруг это разные переменные? Node это класс, то есть ссылочный тип. После первого выполнения метода Add, head и tail ссылаются на один и тот же объект(назовём его #1) head == #1 && tail == head. После второго запуска head == #1 && tail == #2 && head.next == tail. После третьего head == #1 && tail == #3 && head.next == #2 && head.next.next == tail. Переменная tail.next == null всегда, что позволяет находить конец списка начав перечисление с любой точки.
    Ответ написан
    Комментировать
  • Как подключиться к внешнему IP с помощью tcp?

    @none7
    В нынешних условиях когда каждое подключение проходит через домашний роутер с NAT, нет не у кого "белого" ip-адреса(глобального, внешнего), кроме как у серверов. Даже если "белый" ip-адрес выдаётся провайдером роутеру(что не факт), то нужно сперва пробросить порт через UPnP или пользователем вручную. В последнем случае пользователь должен указать Вашей программе адрес и порт. Конечно есть ещё IPv6, но тех у кого он есть не слишком много. Есть Teredo, но включать его без спроса пользователя не стоит. Да и как любая технология основанная на STUN, работает он не всегда. Метод который работает абсолютно всегда это VPN, который будет проксировать подключения.
    Кстати Ваш код очень наивен. У меня в системе есть сетевые адаптеры виртуальных машин, VPN-соединений, даже могут быть дополнительные Loopback, ну и конечно физические. В каком порядке будут выдаваться адреса всех этих адаптеров?
    Ответ написан
    6 комментариев
  • Как правильно сравнивать ENUM на C#?

    @none7
    FileAttributes не является Enum в привычном смысле. Это битовая маска, то есть число в котором определенные биты имеют определенные значения. Пример откровенно говоря неправильный, так как в ожидаемые директории будет иметь ещё и атрибут Directory, как минимум. Если нужно найти все файлы имеющие один из атрибутов, то код должен выглядеть так
    if(dir.Attributes & (FileAttributes.Hidden | FileAttributes.Offline) != 0)

    Здесь мы складываем биты двух атрибутов и если любой из них не будет равен 0, то условие сработает.
    Ответ написан
    3 комментария
  • Имеет ли смысл использовать асинхронные вызовы в консольных программах Don net core, если алгоритм обработки последователен?

    @none7
    Асинхронность в C# это кооперативная многозадачность. Если многозадачность внутри процесса не нужна, то и асинхронность тоже. Наоборот будет немного медленнее работать и жрать чуть больше памяти. Когда синхронная задача ждёт данных, она не занимает процессорное время. Поток уходит в ядро ОС и диспетчер потоков переключается на другой поток или уводит процессорное ядро в режим ожидания.
    Ответ написан
    Комментировать
  • Как исправить ошибку в VS2019 С# "Индекс находился вне границ массива."?

    @none7
    Максимально возможное значение line1 и line2 равно pow(block_size,3), а размер map pow(block_size,2). Естественно, что значение переполняется.
    Ответ написан
    Комментировать
  • Socket разрывает соединение при движении мышкой, как решить?

    @none7
    Именно в таком варианте, поток сразу после коннекта завершается. Что происходит с объектом(Socket) ссылка на который теряется? Он становится мусором и уничтожается когда сборщик мусора соизволит запуститься. В Вашем случае он запускается при действиях с WPF.
    Ответ написан
  • Как обратиться к значению словаря по ключу Dictionary в C#?

    @none7
    Dictionary строит хеш-таблицу на основе значений возвращённых методом GetHashCode каждого ключа, а так же производит сравнение ключей методом Equals. Класс Dictionary насколько я знаю не переопределяет эти методы, а значит GetHashCode создаётся из указателя. То есть в качестве ключа можно использовать тот самый объект, с которым добавляли новый ключ или если ссылка на него утрачена, то можно его получить через итерацию ключей.
    Никогда не используйте такие конструкции! Dictionary предназначен для работы только с неизменяемыми ключами отдающими всегда один и тот же хеш на основе содержимого объекта.
    Хотя если этот Ваш Dictionary<Dictionary<string, string>, int> создан с компаратором, который из Dictionary<string, string> вычисляет хеш и проверяет равенство объектов по содержимому, то можно просто создать новый Dictionary<string, string> с нужными ключами и значениями и использовать его в качестве ключа. А если не создан то можно создать новый Dictionary на его основе уже с компаратором.
    Ответ написан
    1 комментарий
  • C#| winforms | Кнопка с меню | Как создать кнопку такого вида?

    @none7
    Создаешь кастомный Control. Рисуешь в нём это всё через Graphics с учётом разного размера и разного dpi(попутно проклинаешь себя за свою креативность). Переопределяешь метод OnClick и в нём получаешь координаты клика на поверхности контролла this.PointToClient(Cursor.Position). Высчитав в какой части контролла установлен курсор, реализуешь различное поведение для левой и правой части.
    Если нужна ещё и возможность работы через клавиатуру, без мыши, то придётся создавать два контролла и ставить их рядом.
    Ответ написан
    2 комментария
  • Почему progressBar медленный?

    @none7
    WinForms в принципе штука не быстрая. Попробуйте сократить число установок значения прогрессбара до размера этого контрола в пикселях и не более 10 изменений в секунду.
    Ответ написан
    Комментировать
  • Как применяют Task.Run когда у целевого метода есть параметры?

    @none7
    static Task ProxyRun<T1,T2> (Action<T1> action, T1 arg1,) {
        return Task.Run(() => action(arg1));
    }
    static Task ProxyRun<T1,T2> (Action<T1,T2> action, T1 arg1, T2 arg2) {
        return Task.Run(() => action(arg1, arg2));
    }
    static Task<TResult> ProxyRun<T1,TResult> (Func<T1,T2,TResult> action, T1 arg1,) {
        return Task<TResult>.Run(() => action(arg1, arg2));
    }
    static Task<TResult> ProxyRun<T1,T2,TResult> (Func<T1,T2,TResult> action, T1 arg1, T2 arg2) {
        return Task<TResult>.Run(() => action(arg1, arg2));
    }
    static Task StartNew<T1,T2> (this TaskFactory taskFactory, Action<T1,T2> action, T1 arg1, T2 arg2) {
         return taskFactory.StartNew(() => action(arg1, arg2));
    }

    И таких обёрток Вы можете наплодить сколько душе угодно, даже если не хватит существующих разновидностей Func и Action всегда можно добавить.
    Ответ написан
    Комментировать
  • Как изменить разрядность приложения .net?

    @none7
    Свойства проекта
    Target = "Any CPU"
    Prefer 32-bit = false
    vs2015_proppage_build.png?view=vs-2019

    А вообще хорошим тоном является запуск браузера по умолчанию указывая вместо пути к программе сам URL и установив свойство UseShellExecute=true. Если хочется предоставить выбор браузера, то нужно залезть в HKEY_CLASSES_ROOT и вытащить из него список обработчиков.
    Ответ написан
    Комментировать
  • Как добавить многопоточность в этот код?

    @none7
    Создаёшь функцию c yield return для перечисления всех чисел. Создаёшь Semaphore(30, 30). Затем перебирая эти числа foreach блокируешь семафор(один из 30 слотов) и запускаешь таски, которые по завершению семафор освобождают. Но нужно не забыть, что, выход из foreach не означает завершение всех задач, а так же не стоит забывать про синхронизацию.
    Как то так:
    spoiler

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.Threading;
    
    namespace WindowsFormsApp1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            string key = "";
            char StartChar = '1';
            bool lifeWork = false;
            int line = 0, success = 0;
            private void button1_Click(object sender, EventArgs e)
            {
                key = textBox1.Text;
                StartChar = Convert.ToChar(textBox1.Text.Substring(0, 1));
                timerLog.Interval = 100;
                timerLog.Enabled = true;
                lifeWork = true;
                _ = Work();
            }
    
            IEnumerable<long> GetWorks(string key)
            {
                long value = EncodeBase36(key);
    
                while (true)
                {
                    long newValue = value - 1;
                    if (StartChar != Convert.ToChar(DecodeBase36(newValue).Substring(0, 1)))
                    {
                        break;
                    }
                    yield return newValue;
                    value = newValue;
                }
            }
            private async Task Work()
            {
                var set = new HashSet<Task>();
                var jobsSim = new SemaphoreSlim(30, 30);
                var lockSim = new SemaphoreSlim(1, 1);
    
                foreach(var value in GetWorks(key))
                {
                    if (!lifeWork) break;
    
                    // ограничиваем число потоков
                    // по большей части лимит нужен, чтобы не зафлудить сервер запросами
                    await jobsSim.WaitAsync();
                    Task task = GetResponce(DecodeBase36(value));
                    await lockSim.WaitAsync();
                    set.Add(task);
                    lockSim.Release();
                    _ = task.ContinueWith(async(t) => {
                        await lockSim.WaitAsync();
                        success++;
                        set.Remove(t);
                        lockSim.Release();
                        jobsSim.Release();
                    });
                    line++;
                }
    
                await lockSim.WaitAsync();
                var tasks = set.ToList();
                lockSim.Release();
    
                await Task.WhenAll(tasks);
    
                MessageBox.Show("Off work");
            }
            private async Task GetResponce(string value)
            {
                // Тут будет происходить гет запрос и прочая работа с строкой . По времени занимает от 5 до 15 секунд.
                // Так что код сделла чисто для симуляции времени работы .
                Random rnd = new Random();
                int timeOutn = rnd.Next(5, 15);
                await Task.Delay(timeOutn * 1000);
            }
            public static long EncodeBase36(string number, int radix = 36)
            {
                const string Digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    
                if (radix < 2 || radix > Digits.Length)
                    throw new ArgumentException("The radix must be >= 2 and <= " +
                        Digits.Length.ToString());
    
                if (String.IsNullOrEmpty(number))
                    return 0;
    
                // Make sure the arbitrary numeral system number is in upper case
                number = number.ToUpperInvariant();
    
                long result = 0;
                long multiplier = 1;
                for (int i = number.Length - 1; i >= 0; i--)
                {
                    char c = number[i];
                    if (i == 0 && c == '-')
                    {
                        // This is the negative sign symbol
                        result = -result;
                        break;
                    }
    
                    int digit = Digits.IndexOf(c);
                    if (digit == -1)
                        throw new ArgumentException(
                            "Invalid character in the arbitrary numeral system number",
                            "number");
    
                    result += digit * multiplier;
                    multiplier *= radix;
                }
    
                return result;
            }
    
            private void timerLog_Tick(object sender, EventArgs e)
            {
                lbLine.Text = line.ToString();
                lbSuccess.Text = success.ToString();
            }
    
            public static string DecodeBase36(long decimalNumber, int radix = 36)
            {
                const int BitsInLong = 64;
                const string Digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    
                if (radix < 2 || radix > Digits.Length)
                    throw new ArgumentException("The radix must be >= 2 and <= " +
                        Digits.Length.ToString());
    
                if (decimalNumber == 0)
                    return "0";
    
                int index = BitsInLong - 1;
                long currentNumber = Math.Abs(decimalNumber);
                char[] charArray = new char[BitsInLong];
    
                while (currentNumber != 0)
                {
                    int remainder = (int)(currentNumber % radix);
                    charArray[index--] = Digits[remainder];
                    currentNumber = currentNumber / radix;
                }
    
                string result = new String(charArray, index + 1, BitsInLong - index - 1);
                if (decimalNumber < 0)
                {
                    result = "-" + result;
                }
    
                return result;
            }
        }
    }

    Ответ написан
    Комментировать
  • Где же все-таки находится ссылка на таблицу методов в .NET?

    @none7
    Когда не знаешь чему верить, то верь отладчику.
    Там так:
    static void test(object o) {
        Type t = o->type; // offset 0
        IntPtr *vt = t->vtable_of_type; // offset 0x28 на x86
        vt[3](); // call
    }
    Ответ написан
    Комментировать
  • Почему возникает NullReferenceException?

    @none7
    Нельзя просто взять и создать Text. Его должен создавать GameObject. Пример.
    Ответ написан
  • Проблема в изучении c# ,зачем и как использовать возможности языка?

    @none7
    Ивенты это просто сахар для колбэков объекта, внутри там Form.OnClickEventAdd(Delegate d). Колбэки объекта нужны для долгоживущих объектов вроде оконных форм или ячейки записи в бд с уведомлением об изменении, записям в книге контактов с событиями по появлению онлайн, инициализации им звонка, изменение контактом своей иконки. В общем событий каждый объект может генерировать уйму. Как альтернатива, есть наследование с переопределением виртуальных методов, но оно не позволяет отправить сигнал множеству связанных объектов, а так же можно писать лапшекод, который без абстракций вызывает методы других классов по событию.
    Назначение тех или иных конструкций должно становится понятным при написании максимально абстрактного кода.
    Ответ написан
    Комментировать
  • Как мне изменить IP адреса в пакете ICMP?

    @none7
    API драйвера отправляющего ICMP запросы не предусматривает выбор адреса отправки. Вы можете запускаться с админскими привилегиями и использовать RAW-сокеты, для самостоятельного формирования и разбора IP-пакетов. И это даже можно сделать на C# через обычный System.Net.Sockets.Socket. Только вот очень вероятно, что если Вы отправите пакет с адресом не тем, что Вам выдал провайдер, то он такой пакет дропнет.
    Ответ написан
    Комментировать
  • Как ежесекундно проверять данные в потоке Stream (FileStream, StreamReader, CryptoStream)?

    @none7
    Оберни inputStream или outputStream в класс реализующий Stream. Таким образом класс CryptoStream сам уведомит Ваш код о любых изменениях. Эти изменения тут же писать в прогрессбар, если конечно изменение значительно отличается от данных которые уже отображены.
    Ответ написан
    2 комментария