20.08.2017 Планы MS на .Net платформу -- кто объяснит?
 
Как то официально никто ничего не объявляет но что-то происходит.

Судя по исходникам и NuGet-пакетам, все библиотеки MS делает под .Net Core. Старые под классический .Net уже даже не обновляет. Тот же EF сейчас 6.1.3 от March 11, 2015.

Но! .Net Core то еще сырой, в нем нет всего того пласта наработок/библиотек что в классическом.

И сейчас такое чувство что тебе в доме сняли все окна и двери, сначала хотели ставить новые а потом предлагают ждать пока построят новый дом чтобы в него переселиться.

Где официальное объяснение Microsoft?

20.08.2017 Vs2017 call dword ds:[XXXX] как туда зайти ?
 
Есть экстешнен метод в студийном дизассемблере отображается как
call dword ds:[XXXX]
При попытке нажать F11 просто вызывает не заходя внутрь, как перейти по адресу ds:[XXXX] и посмотреть что там выполняется ?

18.08.2017 Heap corruption - кто виноват?
 
Всем привет, нужна помощь знающих камрадов.

Проблема:
Корраптится куча, приложение падает.

Инфраструктура:
Железо: Виртуальная машина VMware на двух независимых ESXi с якобы живой и неповрежденной памятью
ОС: Microsoft Windows Server 2016 Standard (10.0.14393)
Процесс: Windows-служба x64 под .NET 4.5.2, запущенная под системной учёткой
Отсутствуют антивирусы и подозрительные драйверы.

Падения происходят раз в несколько дней. Традиционно для коррапта кучи — в произвольных местах, при обращении к памяти.
Проблема не поддаётся воспроизведению и стреляет у одного человека из десятков тысяч.

Поковырял WinDbg, куча действительно повреждена:

0:027> !VerifyHeap
object 0000021701b6f728: bad member 0000021701B7C9F8 at 0000021701B6F738
Last good object: 0000021701B6F710.
...
Could not request method table data for object 0000021701B7C9F8 (MethodTable: 39E70380864F9B7C).
Last good object: 0000021701B7C9D0.


Выяснил, что жертвой стали элементы одного из массивов:

> !DumpArray /d 0000021701942910
Name:        RootNamespace.FileSession[]
MethodTable: 00007ff87d5d6de0
EEClass:     00007ff8d8498af0
Size:        272(0x110) bytes
Array:       Rank 1, Number of elements 31, Type CLASS
Element Methodtable: 00007ff87b627750
[0] 0000021701bd0660
[1] 0000021701bd06a8
[2] 0000021701bd06f0
[3] 0000021701bd0738

> dq 0000021701942910
00000217`01942910  00007ff8`7d5d6de0 00000000`0000001f
00000217`01942920  00000217`01bd0660 00000217`01bd06a8
00000217`01942930  00000217`01bd06f0 00000217`01bd0738
00000217`01942940  00000217`01bd0780 00000217`01bd07c8
00000217`01942950  00000217`01bd0810 00000217`01bd0858
00000217`01942960  00000217`01bd08a0 00000217`01bd0900
00000217`01942970  00000217`01bd0948 00000217`01bd0990
00000217`01942980  00000217`01bd09d8 00000217`01bd0a20

Вначале идёт таблица методов, количество элементов (31 штука) и далее указатели на элементы массива.

Посмотрим что лежит на месте первого элемента:
> !objsize 00000217`01bd0660 
sizeof(0000021701bd0660) = 72 (0x48) bytes (RootNamespace.FileSession)

> dq 00000217`01bd0660 L9
00000217`01bd0660  00007ff8`7b627750 00000000`00000001
00000217`01bd0670  486b85bd`e6c79316 c3d8f969`c90b70ba
00000217`01bd0680  4b059f8e`1e4ddd83 a9c00cf5`7d3ca0a7
00000217`01bd0690  46de7a50`833a6808 6dfea71f`5f3810b8
00000217`01bd06a0  00000000`00000000



Теперь плохой массив:
!DumpArray /d 0000021701b6f728
Name:        RootNamespace.FileSession[]
MethodTable: 00007ff87d5d6de0
EEClass:     00007ff8d8498af0
Size:        272(0x110) bytes
Array:       Rank 1, Number of elements 31, Type CLASS
Element Methodtable: 00007ff87b627750
[0] 0000021701b7c9f8
[1] 0000021701b7ca40
[2] 0000021701b7ca88
[3] 0000021701b7cad0


И его первый элемент:
> dq 0000021701b7c9f8 L9
00000217`01b7c9f8  39e70380`864f9b7e 64017283`9c955ef7
00000217`01b7ca08  e7694b13`d6b9417a 7049840e`f4aaffbd
00000217`01b7ca18  37a6b685`02f4fade da40d413`1f15d547
00000217`01b7ca28  f47180d7`d905900a 67649a05`b2eb5deb
00000217`01b7ca38  0d708b24`098c06b4


По адресу 00000217`01b7c9f8 лежит не элемент массива, а обыкновенный мусор.

Но если мы отмотаем память немного назад, то обнаружим...

00000217`01b7c9e0  00000000`00000000 00000002`00000002
00000217`01b7c9f0  07745b33`00000000 39e70380`864f9b7e
00000217`01b7ca00  64017283`9c955ef7 e7694b13`d6b9417a
00000217`01b7ca10  7049840e`f4aaffbd 37a6b685`02f4fade
00000217`01b7ca20  da40d413`1f15d547 f47180d7`d905900a
00000217`01b7ca30  67649a05`b2eb5deb 0d708b24`098c06b4
00000217`01b7ca40  ce6ca3df`a30a02f1 9d9f32ae`eaa97bb7
00000217`01b7ca50  36b0ac8a`91d534b1 f58dbd9a`2c6c8055
00000217`01b7ca60  c2b5f5c5`d2d982c5 d87fcea8`953f75a3
00000217`01b7ca70  a1f50c94`313b216a 2651d93a`7f1b2eb0
00000217`01b7ca80  b42d9e5f`265a92d4 d8bbde2c`7c5b1071
00000217`01b7ca90  efae2f4d`07e993e6 998584a8`44f82ef3
00000217`01b7caa0  85a5e61d`7d80cae7 1703c807`bf3c62a4
00000217`01b7cab0  2a1677d9`30847e64 75d48062`37544d6c
00000217`01b7cac0  ee2e1bcf`c2f920aa 84fa15c7`817649aa
00000217`01b7cad0  fa891630`c36247b3 cfb37b15`a2c20424
00000217`01b7cae0  588cf96f`8d9a9b55 5abbb836`66dab3e4
00000217`01b7caf0  dd245fd8`cff527e0 305d965e`88702ad4
00000217`01b7cb00  bc2c5fa8`60c0a7c4 da78741f`3b160725
00000217`01b7cb10  10e18e91`03b009e6 289665d2`a2f45daa
00000217`01b7cb20  987ff2be`b8bca1be 45a2969e`922a2e06
00000217`01b7cb30  67face47`2fa1cee6 005fd79e`81aa3a4f
00000217`01b7cb40  30813582`50286f3b 64624dfb`1a442845
00000217`01b7cb50  66f8af79`e3d568d1 c45acd5d`a0e8a5a6


...что мусор начинается имнно с того места, где раньше находился первый элемент массива.


Меня терзают смутные сомнения, что память, выделенная этому объекту была помечена, как незанятая и просто была переиспользована другим компонентом без каких-либо плясок с unsafe и выходом за границы буфера. Или GC попытался дефрагментировать память, и сделать ему это не удалось.

В связи с этим, у меня несколько вопросов:

1) На забугорных ресурсах кому-то помогает отключение параллелинга в GC

<configuration>
   <runtime>
      <gcConcurrent enabled="false"/>
   </runtime>
</configuration>


Если это не эффект плацебо, значит существуют какие-то гонки между потоками сборщика мусора, которые могут приводить к коррапту кучи? С чем они связаны? От чего зависят? ОС, окружение, железо?

2) Может ли на это как-то повлиять наличие или отсутствие флажка gcServer?

3) Как можно посмотреть — в какие захваченные регионы входит данный фрагмент памяти, кто его аллоцировал, кто держит (поимо !gcroot)?

Подозрительным является то, что "мусор" начинается ровно по границе массива. >_>


Ещё один камень в сторону GC. Другой дамп:


> !VerifyHeap
Could not request method table data for object 000001C88304B5E8 (MethodTable: C4C1934C7B7ABE70).
Last good object: 000001C88304B5C0.

> !objsize 000001C88304B5C0
sizeof(000001c88304b5c0) = 40 (0x28) bytes (System.String)

> db 000001C88304B5C0 L 40
000001c8`8304b5c0  98 de a8 d8 f8 7f 00 00-07 00 00 00 6d 00 6d 00  ............m.m.
000001c8`8304b5d0  2d 00 33 00 30 00 33 00-31 00 00 00 00 00 00 00  -.3.0.3.1.......
000001c8`8304b5e0  00 00 00 00 00 00 00 00-70 be 7a 7b 4c 93 c1 c4  ........p.z{L...
000001c8`8304b5f0  d3 5e e6 47 9c 83 18 2d-c4 8e d0 93 2d 49 4e 72  .^.G...-....-INr

> !gcroot 000001C88304B5C0
Found 0 unique roots (run '!GCRoot -all' to see all roots).
> !gcroot 000001C88304B5E8 
Found 0 unique roots (run '!GCRoot -all' to see all roots).

Ready for finalization 0 objects (000001c8d0102cb0->000001c8d0102cb0)


Ссылок на эти объекты нет, в очереди финализатора их нет, зато есть мусор в чужой памяти.

18.08.2017 EntityFramework: (анти)паттерн Repository
 
Приглашаю высказать свое фи: https://habrahabr.ru/post/335856/

17.08.2017 Nuget вопрос про сборку и версии.
 
Побаиваюсь этой штуки. Пока использовал только чтобы поиграться.
Интересуют такие вопросы:

1) Можно ли как-нибудь гарантировать, что проект соберётся: не будут удалены покаты с сервера, будет доступен или вообще не нужен сервер (например, его случайно не заблокирует роскомпозор, или, как это бывает у мелкософта "В работе Skype произошел глобальный сбой"(с)Интерфакс).

2) Можно ли как-нибудь гарантировать, что разработчики работают с одной и той же версией пакетов?

4) Можно ли как-нибудь гарантировать, что билд соберётся ровно с теми версиями пакетов, с которыми сейчас работают разработчики?

3) Можно ли как-нибудь гарантировать, что билд N.0.P.MMM соберётся с версиями пакетов доступными на момент, когда мы первый раз выкатили релиз с этим билдом .

UPD: как сделать всё вышеуказанное.

15.08.2017 Перезагрузка модуля без JIT-отпимизации
 
Есть приложение, собранное в релизной сборке.
Хочется его засуспендить, после чего перезагрузить все модули, отключив JIT-оптимизацию, не выгружая при этом само приложение.
Возможно ли это?

14.08.2017 Error in BiginInvoke delegate
 
Привет,
Из двух потоков приходит информация и выдаётся на UI. Делаю UI update через BeginInvoke. Для этого имеется два делегата, в одном происходит добавление row.
Иногда получаю странную Exception при добавлении новой row в GataDridView:
SystemInvalidOperationException: No row can be added to a DataGridView control that does not have columns. Columns must be added fist.

Столбцы DatagridView инициализируются статически при создании контрола. Поэтому здесь проблем не должно быть.

Кусок кода где возникает Exception:
            

        row = GetRowWithKey(sKey);

                    if (row == null)
                    {                           

                        int index = dataGridViewConfServers.Rows.Add();
                        if (index >= 0)
                        {
                            row = dataGridViewConfServers.Rows[index];
                            row.Tag = obService;
                        }
                        else
                        {
                            throw new Exception("Can't create new row.");
                        }
                            
                    }
                    
                    row.Cells[0].Value = obService.Parent.ExternLookupName == null ? obService.Name : obService.Parent.ExternLookupName;
                    row.Cells[1].Value = obService.EndPoint.ToString();

                    row.Cells[2].Value = obService.State.ToString();

Exception возникает при:
    int index = dataGridViewConfServers.Rows.Add();


Где копать?

14.08.2017 Альтернативы EF Core
 
Перевёл тут небольшой проект для UWP с бд Sqlite на использование EF Core и получил неэффективные множественные запросы SQL и жуткие тормоза. Колдовство с нафигейшен пропертис, чехарда join-ов в запросах LINQ практически не помогли. Помогли только самописные запросы, но я как раз пытался от этого уйти. Буду возвращаться обратно на sqlite-net-pcl — запросы EF Core выполняющиеся секундами(!) на десктопе, абсолютно неприемлемы.

Какая связка бд/ORM самая быстрая для .NET Core по вашим впечатлениям?

10.08.2017 Логгинг с именами функций и номерами строк
 
Как известно, __LINE__, __FILE__ вместе с макро в C# не попали.
StackFrame медленный и вообще не должен компилироваться в native (не пробовал, но рефлексии там вроде нет).
К версии 4.5 появились System.Runtime.CompilerServices, но "в лоб" это тоже не работает. Вариации на тему

    void LogMessage(string format, object[] args,
        [System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
        [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
        [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
    {
        string msg = string.Format(format, args);
        Console.WriteLine("{0} {1}:{2} '{3}'", sourceFilePath, memberName, sourceLineNumber, msg);
    }

компилируется, но естественно не так, как хотелось бы, аттрибуты на сопоставление параметров не влияют. Попробуйте сами

    LogMessage("Hello, world");
    LogMessage("Hello, {0}", "world");
    LogMessage("{0}, {1}", "Hello", "world");

А как (можно ли вообще) на C# написать функцию вроде LogMessage, но работающую и без черезмерного синтаксического оверхеда?

10.08.2017 Сахар для x = x.Method()
 
Приветствую.

Есть методы, которые принимают делегат для обработки последовательностей и часто требуется из него просто вызывать какую-либо функцию/метод элемента без параметров.
Со статическими функциями все получается просто и красиво
sequence.Where(SomeClass.IsNeeded)

, но для экземплярного метода все уже не так замечательно выглядит
sequence.Where(x => x.IsNeeded())

Т.е. появляется лишний никому не нужный синтаксический шум.

Или я загоняюсь и никого не напрягает писать/читать такие вещи?

В последних двух версиях шарпа добавили ну просто лютое количество синтаксического сахара, а такое (а-ля method group только экземплярных методов) никак не запилят.

10.08.2017 "The call is ambiguous..."
 
Из двух методов Outer компилятор (и Mono и Розлин) не может выбрать подходящий. Считает, что подходят оба, хотя реально подходит только один.

public class Foo
{
    public Foo ()
    {
        Outer(Inner); // CS0121: The call is ambiguous between the following methods or properties: 'Foo.Outer(Action)' and 'Foo.Outer(Func<int>)'
    }

    void Inner () {  }
    
    void Outer(Action inner) { }
    void Outer(Func<int> inner) { }
}

public class Foo
{
    public Foo()
    {
        Outer(Inner); // такая же ошибка
    }

    int Inner(int i) => throw new NotImplementedException();

    void Outer(Func<int, bool> inner) { }
    void Outer(Func<int, int> inner) { }
}

Я так понимаю, компилятор не различает типы параметров-делегатов по типу их возвращаемого значения.

Но если делегат не параметр, а локальная переменная, то начинает различать и не путается:
public class Foo
{
    public Foo()
    {
        Action a = Inner; // ок
        Func<int> b = Inner; // void Foo.Inner() has wrong return type
    }

    void Inner() { }
}


Вопрос: это по спецификации так должно быть или недоработка в компиляторах? Спецификацию попробовал почитать, но не осилил.

09.08.2017 Как поймать исключение в момент вызова throw?
 
Всем привет.

Как можно поймать выбрасываемое исключение?
ThreadException и UnhandlelException не предлагать. Оно совершенно точно будет обработано и корректно погашено. Необходимо повесить собственный обработчик именно на throw.

Нечто аналогичное функционалу студии с остановкой отладчика при возникновении исключения.
Возможно ли это?

08.08.2017 EF Core DbContext и ConnectionString
 
Правильно я понимаю, что в EF Core нет возможности забрать провайдера из ConnectionString конфига?
Только жестко вызывать всякие UseSqlite, а из конфига брать только путь к базе?

04.08.2017 Хипстеры, отзовитесь! А вот у кого.NET Core в продакшене?
 
Как живётся? Не жалеете? Часто ли ломаются билды? Часто ли натыкаетесь на баги? Хватает ли библиотек? Хватает ли тулинга? Как в поддержке и сопровождении?

Что хорошего дал вам .NET Core?

03.08.2017 [VS2017] использование .NET Standard 1.3 в .NET FW 4.6
 
Мучаю тут на досуге .NET Standard. Запилил в одном солюшене библиотеку на .NET Standard 1.3 и проект для тестов MSTest этой библиотеки на .NET Framework 4.6. Компилируется всё, но при попытке выполнения теста в методе библиотеки валится исключение:

System.IO.FileNotFoundException: Не удалось загрузить файл или сборку "System.Net.Http, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" либо одну из их зависимостей. Не удается найти указанный файл.


При том, что в зависимостях библиотеки System.Net.Http только версии 4.3.1

Попробовал создать рядом тестовый проект на .NET Core с точно тем же тестовым методом — он отрабатывает без проблем.

Куда копать?

02.08.2017 Майкрософт считает что readoly для reference типов не имеет смысла
 
Коллега откопал следующее правило анализатор
ссылка

CA2104: Do not declare read only mutable reference types
Cause
An externally visible type contains an externally visible read-only field that is a mutable reference type.
Rule Description
A mutable type is a type whose instance data can be modified. The System.Text.StringBuilder class is an example of a mutable reference type. It contains members that can change the value of an instance of the class. An example of an immutable reference type is the System.String class. After it has been instantiated, its value can never change.
The read-only modifier (readonly in C#, ReadOnly in Visual Basic, and const in C++) on a reference type field (pointer in C++) prevents the field from being replaced by a different instance of the reference type. However, the modifier does not prevent the instance data of the field from being modified through the reference type.
Read-only array fields are exempt from this rule but instead cause a violation of the CA2105: Array fields should not be read only rule.
How to Fix Violations
To fix a violation of this rule, remove the read-only modifier or, if a breaking change is acceptable, replace the field with an immutable type.


С одной стороны, как бы логично, но с другой как бы противоречит практике .....

01.08.2017 А можно ли запретить "обычный" вызов метода?
 
Есть у меня хранимые процедуры в SQL-базе и мэппинг на EntityFramework для вызова тех хранимых процедур.
Т.к. это SQL, там бывают довольно длинные списки параметров. Вот, например:

var studies = ctx.usp_SearchStudies(
    patientID:        patientId,
    facilityMRN:      facilityMrn,
    firstName:        firstName,
    lastName:         lastName,
    patientName:      patientName,
    firstAndLastName: firstAndLastName,
    middleName:       middleName,
    patientPrefix:    patientPrefix,
    patientSuffix:    patientSuffix,
    gender:           gender,
    modality:         modality,
    aetitle:          aetitle,
    studyId:          studyId,
    description:      description,
    accession:        accession,
    refPhysician:     refPhysician,
    studyDateFrom:    studyDateFrom,
    studyDateTo:      studyDateTo,
    perPhysician:     perPhysician);


Все или почти все параметры — одного типа (string). Если вызывать процедуру без указания имён параметров, то там запросто можно дико накосячить.
Можно ли как-то средствами C# запретить вызов метода без указания имён параметров? Т.е. чтоб вот такая инструкция сразу давала ошибку компилляции:

var studies = ctx.usp_SearchStudies(
    patientId,
    facilityMrn,
    firstName,
    lastName,
    patientName,
    firstAndLastName,
    middleName,
    patientPrefix,
    patientSuffix,
    gender,
    modality,
    aetitle,
    studyId,
    description,
    accession,
    refPhysician,
    studyDateFrom,
    studyDateTo,
    perPhysician);


?

01.08.2017 Task Context
 
Здравствуйте,

Как в .net можно сделать что-то подобное:

   var task = Task.Factory.StartNew(()=> { ... });

   // Добавить в контекст значение 
   task.Context.Value=100500;

    task.ContinueWith((x,y)=> {

        // А тут его как-то забрать, без глобальных переменных.  
        var value = x.FromContext.Value;



    });

01.08.2017 XLSX в Mono
 
Попробовал либу DocumentFormat.OpenXml 2.7.2. В Windows работает без проблем, а вот в Ubuntu выдает ошибку чего то там нет Root-элемента в XML. Мне именно XLSX нужен, с DOCX вроде работает.

Кто что может порекомендовать?

28.07.2017 Wcf NamedPipe двухсторонний обмен между процессами
 
Приветствую всех
Есть задача реализовать двухсторонний обмен сообщениями между процессами

Насколько правильно использовать для этого дуплексный канал и держать его открытым на протяжении всей работы приложения?
или лучше создать два односторонних канала?
для одностороннего канала как можно отследить, что допустим сервер закрылся? (как я понимаю только пингом..)

 
 
 
 
10.12  .NET Reactor
15.11  n
15.11  C# ClickOnce
 
01.08  Task Context
01.08  XLSX в Mono