• Как отсортировать диалоги пользователя и создать правильный список?

    @Sumor
    Для сортировки в sql-запросе используется конструкция order by.
    Заодно прочитайте про sql-инъекции.
    Ответ написан
  • Winapi, чужое приложение - проблемы с меню и окна отрисовываются только при наведении мыши?

    @Sumor
    Ответ на 4 вопрос:
    Когда деревья были маленькими, а Windows только появилась, то была функция SetActiveWindow, которая делала выбранное окно активным — выбрасывало на первый план. Но программисты любили делать свои окна постоянно активными и вызывали эту функцию слишком часто, от этого иногда система уходила в карусель активных окон. Для предотвращения этого в API Windows появилась функция SetForegroundWindow, которая работает почти также, но в случае частых вызовов окна перестают переключаться, а только начинают мигать в панели задач. Это не особенность компьютеров или программ — это внутренняя кухня. Если система решит, что вы слишком часто переключаетесь - она начнёт просто мигать кнопками.
    Ответ на 3 вопрос:
    Ожидание появление окна — в цикле, по таймеру. Ничего в этом страшного нет. При желании это можно организовать в отдельном потоке.
    Помимо этого есть сложные методы внедрения кода в программу, связанные с хуками приложения или перехватом вызовов функций, но не думаю что ваша задача требует такого сложного вмешательства.
    Ответ на 2 вопрос:
    Видимо у программы так реализован цикл событий, что ваш SendMessage не обработается, пока не придут настоящие события - MOUSE_MOVE, например. Или для диалога нужно текущее активное окно. Или ещё много других подобных причин. Может перед SendMessage должно прийти другое событие.
    В большинстве случаев для имитации действий нужно чтобы окно было активным. Если окно не активное, то имитация в равной степени может работать или не работать.
    Ответ на 1 вопрос:
    Скорее всего меню динамические и создаются по щелчкам мыши и открытию меню. Поэтому вам ничего не остаётся как последовательно имитировать нажатие на меню File, пробег по пунктам меню, и выбор нужного пункта меню — чтобы отработали внутренние механизмы создания подменю.
    Ответ написан
    1 комментарий
  • C# Чтение и удаление строк из начала файла файла

    @Sumor
    При открытии файла вы можете указывать разрешённые совместно с вами действия с файлом.
    В случае C# и FileStream за это отвечает параметр FileShare.
    public FileStream(
    	string path,
    	FileMode mode,
    	FileAccess access,
    	FileShare share
    )

    Программа записи датчика должна открывать файл с параметром FileShare.Read. Тогда остальные программы могут получить одновременный доступ к этому файлу указав параметр FileShare.ReadWrite. Тогда одновременно программа записи с датчика может писать, а вы можете в то же самое время считывать показания.
    Ответ написан
  • Как перевести проект на c# SQL Server на SQL Server Compact Edition?

    @Sumor
    Основная проблема — совместимость типов и использование хранимых процедур.
    SQL Compact Edition поддерживает только таблицы и не поддерживает процедуры, функции и триггеры. Полный список отличий представлен в таблицах от Microsoft
    В коде достаточно поменять System.Data.SqlClient на System.Data.SqlServerCe.
    Классы с Sql* на SqlCe*, например, SqlConnection на SqlCeConnection.
    System.Data.SqlServerCe нужно дополнительно подключать в проект в ссылках (references).
    Ответ написан
    Комментировать
  • Почему не соединяется SQL Local DB?

    @Sumor
    Нужна установка .Net 4.0.2 или выше, например, 4.5.
    Помимо этого нужна установка MSSQL Server Express.
    Строка подключения правильная.
    Ответ написан
  • Почему выводится ошибка при добавлении записи в MS SQL?

    @Sumor
    executeQuery вызывается для SELECT запросов, которые возвращают результирующие наборы.
    В вашем случае нужно использовать executeUpdate, который предназначен для команд UPDATE INSERT DELETE, которые результирующие наборы не возвращают.
    Ответ написан
    Комментировать
  • C# Word Interop: как объединить две таблицы в документе Word?

    @Sumor
    Часто удобнее уже иметь заранее таблицу готового вида и добавлять туда строки с данными, чем объединять таблицы, так как при объединении таблиц Ворд подгоняет размеры колонок и они могут оказаться вполовину меньше ожидаемой.
    В целом же, для объединения двух таблиц достаточно просто удалить абзацы между ними.
    Ответ написан
    Комментировать
  • C# - как перевести строку в utf16 и сделать маршалинг?

    @Sumor
    Можно воспользоваться преобразованием из string в массив байтов — функция
    Encoding.Unicode.GetBytes для UTF16
    Encoding.UTF8.GetBytes для Utf8 и тд
    При этом нужно не забыть обеспечить в конце строки нулевой символ.
    Если строка будет использоваться для COM - выделение памяти через AllocCoTaskMem, если для вызовов неуправляемого кода — AllocHGlobal.
    Ну и не забыть освободить память после использования.
    var str = "abc\0";
    var UTF16data = Encoding.Unicode.GetBytes(str);
    var len = UTF16data.Length;
    IntPtr pData = Marshal.AllocCoTaskMem(len);
    // IntPtr pData = Marshal.AllocHGlobal(len);
    
    … использование pData …
    
    Marshal.Copy(UTF16data, 0, pData, len);
    Marshal.FreeCoTaskMem(pData);
    // Marshal.FreeHGlobal(pData);
    Ответ написан
    Комментировать
  • WPF Доступ к объектам другой страницы

    @Sumor
    Из вопроса неочевидно как всё-таки связаны Page1 и Page2.
    Если из Page1 вызывается Page2, то самый простой способ при вызове создать экземпляр Page2 и присвоить значение переменной.
    Navigate(new Page2(){ variable = "abc"});
    Можно использовать для передачи объект состояния перехода — дополнительный параметр метода Navigate. Пример из MSDN:
    void goButton_Click(object sender, RoutedEventArgs e)
    {
        this.NavigationService.Navigate(new ContentPage(), DateTime.Now);
    }
    void NavigationService_LoadCompleted(object sender, NavigationEventArgs e)
    {
        DateTime requestDateTime = (DateTime)e.ExtraData;
        string msg = string.Format("Request started {0}\nRequest completed {1}", requestDateTime, DateTime.Now);
        MessageBox.Show(msg);
    }


    Ну и самый нерекомендуемый способ - использование статических свойств для передачи состояния.
    Ответ написан
    2 комментария
  • Не могу связать ObservableCollection с ListView (WPF)?

    @Sumor
    Скорее всего у вас некорректно задан Binding у ListView.
    Попробуйте явно задать, например, в конструкторе после инициализации:
    tProfiler.ItemsSource = queryInf;
    Всё должно получиться.
    Ответ написан
  • Как сделать 200 update c#/mssql ещё быстрее (с#/mssql) ?

    @Sumor
    Для того, чтобы оценить где можно улучшить нужно в первую очередь посмотреть планы выполнения update и времена в профайлере SQL-сервера.
    1. Каждый индекс отнимает время на своё обновление. Возможно можно уменьшить количество индексов. Иногда выгодней их удалять и заводить заново после операций обновления. Тоже касается вычислимых полей, значения которых хранятся в таблице. Если переделать ключ таблицы в кластерный индекс, то это может улучшить время поиска и обновления записей.
    2. Тригеры. Их можно также отключить перед выполнением пакета и включить после выполнения.
    3. Уменьшить количество операций Update путём их объединения по каким-то признакам. Уменьшить количество обновлений в одной транзации.
    4. Если позволяет структура базы данных, то возможно быстрее будет работать связка delete/insert. В этом случае можно включить режим Bulk Insert, который пишет данные сразу в таблицы минуя лог транзакций.
    5. Модель восстановления — simple, full или bulk logged. Возможно в вашем случае модель full даст выигрыш в обновлении данных, но вы можете потерять в месте на жёстком диске и времени сохранения базы данных.
    6. Физическое расположение контейнеров. Можно физически разнести таблицы, индексы и лог на три разных диска - тогда могут улучшиться временные показатели.
    7. Использование секционированных таблиц и индексов. Возможно, если обновление происходит только в определённой части огромной таблицы, например, только в записях последнего года, то имеет смысл разбить её на секции.

    В любом случае нужно исследовать каждую задачу оптимизации индивидуально. Нужно попробовать исключить каждый фактор и замерить время без него. Например, временно удалить все индексы в таблице и запустить пакет обновления.
    Ответ написан
    Комментировать
  • Что, кроме потоков, есть в c#?

    @Sumor
    Вопрос скорости выполнения зависит слишком от многих факторов. В первую очередь от процедуры, которую вы хотите исполнять в потоке. Можно запустить одновременно множество потоков, но они будут упираться в ограничения в других местах - например, есть ограничение на количество подключений по сети, к БД, к жёсткому диску, ну, и собственно, количество процессоров.
    Для исследовательских задач алгоритм улучшения примерно такой — сначала реализуете алгоритм, выполняющий поставленную задачу самым простым для реализации способом. Смотрите на времена выполнения, в частности можно и нужно использовать различные профайлеры, счётчики ресурсов и тп. Если после этого времена не устраивают - смотрите где происходят наибольшие потери — эти места и нужно править в первую очередь.
    Повторюсь — улучшать нужно не то, что кажется исходя из каких-то там теоретических соображений, а то что реально показывает профайлер или трассировка выполнения.
    Распределение вычислений по потокам может дать выигрыш в случае многопроцессорных систем (а может и не дать). При этом надо учитывать, что:
    1. Потоки нужно создавать. Если расчётная функция выполняется сопоставимо со временем создания потока — нет смысла создавать поток.
    2. Потоками нужно управлять. Им нужно передавать исходные данные, а также получать результаты. Потоки могут конкурировать и блокировать друг друга за ресурсы приложения, очереди с исходными данными или за способность записать результат.
    3. Потоки могут быть независимыми или реализован конвейер. Во втором случае нужно правильно и согласовано организовать передачу данных между потоками — иначе все преимущества конвейерных вычислений уйдут в инфраструктуру обмена.

    Можно реализовать следующим способом:
    Запускается настраиваемое число потоков, которые в цикле берут данные из очереди типа ConcurrentQueue, обрабатывают их и результат кладут в кучу ConcurrentBag.
    Указанные коллекции — потокобезопасные, то есть возможна безопасная работа с ними одновременно из многих потоков.
    В моей задаче, для 4-х ядер оптимальное среднее время выполнения задачи с очередью 20000 элементов достигалось на 3-5 потоках.
    Ответ написан
    Комментировать
  • Есть ли в С# замена type паскаля?

    @Sumor
    Можно использовать такую конструкцию до объявления классов:
    using MyInt = System.Int32;
    Или, если класс не запечатанный(sealed), можно от него отнаследоваться:
    public class MyIntList : List<int>{}
    Ответ написан
    Комментировать
  • Транзакция в MS SQL - как осуществить проверку?

    @Sumor
    Нужно использовать в дополнение к транзакциям механизм блокировок.
    Например, для MSSQL www.sql.ru/articles/mssql/2004/04110303advancedloc...

    В твоём случае это будет примерно так:
    BEGIN TRAN BUYITEM;
    
    Select cash from users (UPDLOCK) WHERE id = @id;
    
    UPDATE users SET cash = cash-@cash WHERE id = @id;
    INSERT INTO items VALUES (@id, @item);
    
    COMMIT TRAN BUYITEM;

    Пока одна транзакция что-то пишет, считает и обновляет — другие будут ждать её завершения.
    Ответ написан
    2 комментария
  • Как средствами WPF отрисовать график функции, используя Canvas?

    @Sumor
    Вычисляются значения функции с определённым шагом, дальше в колекцию PathFigure добавляются объекты типа LineSegment (если не нужно интерполировать) или другой наследник класса PathSegment, соответствующий нужной интерполяции. Например, кривыми Безье третьего порядка — PolyBezierSegment.
    Point указывает новую точку, до которой нужно продолжить график.
    При расчётах нужно учитывать, что у Canvas начало координат находится в левом верхнем углу, а ось Y направлена вниз. Либо учитывать при расчётах следующей точки, либо использовать трансформации Canvas.
    Должно получиться вроде этого
    <Canvas>
        <Path Stroke="Black" StrokeThickness="1">
            <Path.Data>
                <PathGeometry>
                    <PathFigure>
                        <LineSegment Point="100,100"/>
                        <LineSegment Point="150,120"/>      
                        <PolyBezierSegment Points="170,120 190,100 200,160 220,140"/>
                    </PathFigure>
                </PathGeometry>
            </Path.Data>
        </Path>    
    </Canvas>
    Ответ написан
    3 комментария
  • Как запустить несколько потоков одновременно в c#?

    @Sumor
    С филосовской точки зрения всё равно потоки не стартуют одновременно, так как процессор-то один.
    Но с точки зрения программирования можно предложить следующее решение с потоками-стартерами рабочих потоков.
    class Program
    {
    static List<Thread> threads = new List<Thread>();   // Список потоков
    static int threadCount = 10;                        // Число потоков
    static ManualResetEvent startEvent = new ManualResetEvent(false);   // Событие для старта рабочих потоков
    static volatile int starterCount = 0;               // Счётчик запущенных потоков. volatile показывает, что переменная будет изменяться в различных потоках и её не надо оптимизировать
    static object LockObject = new object();            // Блокировка для изменения переменной starterCount
    
    static void Main(string[] args)
    {
        // Создаём пул потоков
        for (int i = 0; i < threadCount; i++)
        {
            Thread thread = new Thread(Work);
            threads.Add(thread);
        }
        // На старт — запускаем стартовые потоки и ждём их запуска
        foreach (var thread in threads)
            new Thread(Starting).Start(thread);
        while (starterCount < threadCount) Thread.Sleep(1);
        // Внимание — к этому моменту все стартовые потоки запустились и ожидают на WaitOne()
        Thread.Sleep(100);
        // Марш — установка события отпускает приостановленные потоки
        startEvent.Set();
    
        while (true) ;
    }
    
    static void Starting(object paramThread)
    {
        lock (LockObject)
        {
            starterCount++;
        }
        startEvent.WaitOne();
        (paramThread as Thread).Start();            
    }
    
    static void Work()
    {
        return;
    }
    }
    Ответ написан
    1 комментарий