Ответы пользователя по тегу C#
  • Как остановить выполнение SqlCommand?

    @Sumor
    Cancel пытается отменить запрос и пытается передать это на SQLServer. Если запрос длительный и состоит из отдельных шагов, и эти шаги ещё на начали исполняться, то команда прервётся. Если идёт выдача, то она тоже может прерваться.
    Вам же, если вы прервались, не обязательно продолжать считывать - прерывайтесь, больше не вызывайте Read(), закрывайте reader и извещайте пользователя. При использовании BeginExecuteReader вы сможете проще организовать процесс ожидания и прерывания, но чуть сложнее процесс получения данных.

    В одном проекте я поступал несколько по-другому. Я быстро получал идентификаторы объектов, релевантных запросу, а затем спокойно в отдельном потоке начитывал строчки с данными (много медленных колонок). Процесс этот контролировался мной и мог прерваться в любой момент. В качестве бонуса получается правильный прогрессбар.
    Ответ написан
    Комментировать
  • Где найти примеры и материалы для самостоятельного освоения BeginExecuteReader?

    @Sumor
    А чем вам не нравится пример из MSDN?
    msdn.microsoft.com/ru-ru/library/1a674khd(v=vs.110...
    Вы можете проверять состояние IAsyncResult не в цикле, как в примере, а в таймере, попутно отображая прогресс выполнения.
    Ответ написан
    Комментировать
  • Как реализовать передачу строк в C++ dll, изменить ее и вернуть в .Net C# проект?

    @Sumor
    Для описания и вызова функций из обычных dll на c/c++ используется класс Marshal.
    Можно выделить память, преобразовать строку, структуру в неуправляемую память и обратно.
    В примере вызывается функция GetComputerName, которая заполняет выделенную в программе память, а затем результат преобразуется в string и выводится на консоль.
    class Program
    {
        static void Main(string[] args)
        {
            // Выделение памяти из неуправляемой области
            // Получаем обычный указатель для использования в c/c++ функциях
            var pComputerName = Marshal.AllocHGlobal(256);
            // Вызываем описанную внешнюю функцию
            // Она будет работать непосредственно с памятью по указателю
            int size = 256;
            GetComputerName(pComputerName, ref size);
            // Переводим результат в управляемый вид
            var str = Marshal.PtrToStringUni(pComputerName);
            Console.WriteLine(str);
            // Обязательно освобождаем выделенную память
            Marshal.FreeHGlobal(pComputerName);
            Console.ReadLine();
        }
    
        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
        public static extern void GetComputerName(IntPtr pComputerName, ref int size); 
    }
    Ответ написан
  • Как заставить Coded UI видеть символы в юникоде?

    @Sumor
    Можете использовать индекс, вместо названия столбца.
    TestContext.DataRow[0].ToString();
    Ответ написан
  • Как нарисовать элементы поверх карты или SVG изображение карты ?

    @Sumor
    Вот этот компонент может отображать данные с OSM, и на нём можно дорисовывать векторные элементы:
    ComponentOne Maps
    Ответ написан
  • C#: построение тяжелых графиков в реальном времени

    @Sumor
    ComponentOne
    DevExpress

    NB: Если точки поступают с частотой 50 Гц, то это не означает, что нужно обновлять графики с той же частотой. Достаточно накапливать данные и дорисовывать графики с частотой 1-5 Гц.
    Ответ написан
    1 комментарий
  • Как завершить поток, в котором прослушивается порт

    @Sumor
    Abort не прерывает исполнение потока, а лишь сообщает ему, что кто-то хочет его прервать.

    Замените while(true) на while(Thread.CurrentThread.ThreadState & (ThreadState.AbortRequested)
    Ответ написан
    Комментировать
  • Может ли primary key быть типа string?

    @Sumor
    Это зависит от БД. В SQL Server можно. В вашей СУБД — очевидно нельзя. Добавьте в схему таблицы identity поле и оно автоматически заполнится при добавлении строк.
    Ответ написан
  • 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.
    Строка подключения правильная.
    Ответ написан
  • 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>{}
    Ответ написан
    Комментировать
  • Как средствами 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 комментария