Ответы пользователя по тегу C#
  • C#| winforms | Кнопка с меню | Как создать кнопку такого вида?

    @none7
    Создаешь кастомный Control. Рисуешь в нём это всё через Graphics с учётом разного размера и разного dpi(попутно проклинаешь себя за свою креативность). Переопределяешь метод OnClick и в нём получаешь координаты клика на поверхности контролла this.PointToClient(Cursor.Position). Высчитав в какой части контролла установлен курсор, реализуешь различное поведение для левой и правой части.
    Если нужна ещё и возможность работы через клавиатуру, без мыши, то придётся создавать два контролла и ставить их рядом.
    Ответ написан
  • Почему 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 сам уведомит Ваш код о любых изменениях. Эти изменения тут же писать в прогрессбар, если конечно изменение значительно отличается от данных которые уже отображены.
    Ответ написан
  • Асинхронный UDP-клиент на C#. Где происходит получение данных?

    @none7
    Там ниже код
    Task.Run(() =>
                {
                    IPEndPoint ipEndPoint = null;
    
                    while (true)
                    {
                        try
                        {
                            var receivedBytes = _client.Receive(ref ipEndPoint);
                            TaskCompletionSource<byte[]> tcs;
                            if (_tcsDictionary.TryGetValue(ipEndPoint, out tcs)) tcs.SetResult(receivedBytes);
                        }
                        catch (SocketException)
                        {
                            ;//при невозможности соединения продолжаем работать
                        }
    
                    }
                });

    Здесь при помощи tcs.SetResult данные передаются в первый кусок кода.
    Ответ написан
  • В чём принцип работы STUN?

    @none7
    STUN нужен, чтобы узнать свой внешний ip и, что важнее внешний порт ассоциированный с внутренним. Ещё STUN сервер нужен, чтобы выяснить тип NAT. Если у одного из Вас Symmetric, а у другого RestrictedCone или PortRestrictedCone, то можно забыть про P2P. Больше STUN не на что не годен. В случае VoIP, клиенты желающие соединиться обмениваются через SIP адресами полученными через STUN и направляют на друг друга поток трафика. В случае restricted NAT передача должна начаться с обеих сторон иначе NAT принимающей стороны решит, что пакеты нужно отбросить. Teredo например начинает слать пакеты пустышки, получение которых символизирует, что соединение уже установлено. Вы можете написать собственный Teredo клиент по спецификации, она довольно простая.
    STUN такой куций протокол потому, что он лишь дополнение для SIP. Но это не мешает использовать его для своих нужд.
    Ответ написан
  • Как запустить C# DLL библиотеку под office для х86 и х64?

    @none7
    У меня были устаревшие сведения. Так, что в комментарии я наврал. Regasm которым Вы пользуетесь он 32-битный и все его записи попадают в WOW64 в том числе и записи в реестр. Используйте консоль для сборки x64, чтобы regasm писал в правильную ветвь реестра. Чтобы корректно установить библиотеку Вам понадобится вызвать 2 разных regasm!
    Ответ написан
  • Передаю не правильный заголовок в POST запрос (C#)?

    @none7
    Не можете форматировать json руками, используйте классы
    JsonSerializer.Serialize(new { input = "We make the world a better place" , lang = "ja"})
    Ответ написан
  • Почему в веб-приложении, на странице, выводиться 8, а не 4?

    @none7
    Это связано с тем, что анонимный метод вызывается дважды. Один раз для логов, второй для отправке клиенту. Не записывайте в переменные родительского метода ничего.
    Ответ написан
  • Как организовать доступ двух потоков к общей переменной в C#?

    @none7
    В данном конкретном случае, нет. Переменная str это указатель, с точки зрения процессора это примитивный тип данных. Самое страшное, что могло бы произойти это мешанина битов в переменной, но процессор сам разруливает такие ситуации с примитивными типами. Со структурами тот же трюк не пройдёт.
    Ответ написан
  • Что из себя представляют объекты примитивных значимых, ссылочных типов?

    @none7
    Все свойства ValueType открыты, у базовых типов вроде int, свойств вообще нет, они прибиты к ValueType для красоты. Они хранилище для чисел, просто набор битов, примитивнее просто некуда, с ними работают машинные инструкции, а не методы. В случае локальных переменных они вполне могут существовать лишь в регистрах процессора или вообще стереться за ненадобностью. Это и есть разница между age и _age, другой разницы нет. Что касается методов, то как код фреймворка должен вызывать скрытые методы? Не существует такой вещи.
    Какого рода дескрипторы? Гуглёжь находит дескрипторы файлов и окон...
    P.S. Сложные книги предполагают, что Вы имеет базовое понимание работы компьютера и понимаете Си.
    Ответ написан
  • При запуске приложения или при сохранении выдает ошибку, что "недостаточно памяти для продолжения выполнения программы"?

    @none7
    Диспетчер задач врёт, у Вас ещё меньше памяти. Свопа осталось 62 мб, то есть если программа под распаковку картинки просит больше, то случится фейл, а языки с gc память резервируют крупными блоками. Картинки жрут чуть больше чем 4 байта на пиксель, гифки тоже для каждого кадра, тут уж сами считайте сколько это памяти. Что делать? Правильный вариант раскошелится на память, цена вопроса на али около 1500р. Неправильный, затянуть пояс потуже. Увеличить своп, перейти на 32-битную винду, грохнуть дискорд и другие прожорливые приложения и ненужные службы. В крайнем случае кодить в легковесном редакторе, а отлаживать по старинке, выводом информации в лог.
    Ответ написан
  • Как в C# подключить свою библиотеку dll при работе из консоли?

    @none7
    shared1.cs
    public class MyShared {
        public static string getHello() => "Hello, World";
    }
    prog.cs
    class MyProgram {
    	static void Main(string[] args) => System.Console.WriteLine(MyShared.getHello());
    }

    csc /t:library shared1.cs
    csc /t:exe /r:shared1.dll prog.cs
    Ответ написан