Не удается подключиться к API dotMemory, пока он не запустит приложение
У меня есть следующее, чтобы запустить API профилирования:
while (!MemoryProfiler.IsActive || !MemoryProfiler.CanControlAllocations)
{
_presenter.WriteLine("Press enter to try to attach.");
Console.ReadKey();
Thread.Sleep(250);
}
MemoryProfiler.EnableAllocations();
Тем не менее, если я запускаю это и присоединяю к нему dotMemory, то MemoryProfiler.CanControlAllocations
всегда false
(MemoryProfiler.IsActive
становится true
).
Если я позволю dotMemory запустить приложение, то оно будет работать как положено, и оба они оценят true
,
Если, однако, я заменяю while
с Console.Read()
и if
как это:
Console.WriteLine("Press enter when connected.");
Console.ReadLine();
if (MemoryProfiler.IsActive && MemoryProfiler.CanControlAllocations)
{
MemoryProfiler.EnableAllocations();
}
Тогда все работает нормально.
В чем дело? Как это while
поведение изменения цикла, как это?
Более странное поведение
Если я запускаю следующее (с if
закомментирован)
Console.WriteLine("Press enter when connected.");
Console.ReadLine();
Console.WriteLine($"MemoryProfiler.IsActive: {MemoryProfiler.IsActive}");
Console.WriteLine($"MemoryProfiler.CanControlAllocations: {MemoryProfiler.CanControlAllocations}");
//if (MemoryProfiler.IsActive && MemoryProfiler.CanControlAllocations)
MemoryProfiler.EnableAllocations();
Console.WriteLine("Attached.");
Тогда я получаю вывод:
Press enter when connected.
MemoryProfiler.IsActive: True
MemoryProfiler.CanControlAllocations: False
а затем исключение на вызов EnableAllocations()
:
JetBrains.Profiler.Windows.Api.ProfilingApiException: 'Method isn't supported'
Я ожидал бы этого, потому что MemoryProfiler.CanControlAllocations
является false
,
Однако, если я раскомментирую if
заявление:
Console.WriteLine("Press enter when connected.");
Console.ReadLine();
Console.WriteLine($"MemoryProfiler.IsActive: {MemoryProfiler.IsActive}");
Console.WriteLine($"MemoryProfiler.CanControlAllocations: {MemoryProfiler.CanControlAllocations}");
if (MemoryProfiler.IsActive && MemoryProfiler.CanControlAllocations)
MemoryProfiler.EnableAllocations();
Console.WriteLine("Attached.");
Затем все работает снова, и я получаю ожидаемый результат:
Press enter when connected.
MemoryProfiler.IsActive: True
MemoryProfiler.CanControlAllocations: False
Attached.
1 ответ
MemoryProfiler.CanControlAllocations
всегда false
в режиме подключения, потому что выделения не могут быть собраны. Посмотри пожалуйста COR_PRF_ALLOWABLE_AFTER_ATTACH
, COR_PRF_ENABLE_OBJECT_ALLOCATED
а также COR_PRF_MONITOR_OBJECT_ALLOCATED
флаги в corprof.idl
PS MemoryProfiler.EnableAllocations()
а также MemoryProfiler.DisableAllocations()
всегда будет выдавать исключение в режиме подключения.
Следующий код будет работать как в режиме запуска, так и в режиме подключения:
while (!MemoryProfiler.IsActive)
Thread.Sleep(500);
// do something here #1
MemoryProfiler.Dump();
// do something here #2.1
if (MemoryProfiler.CanControlAllocations)
MemoryProfiler.EnableAllocations();
// do something here #2.2, here will be collected allocations, but only in start mode
if (MemoryProfiler.CanControlAllocations)
MemoryProfiler.DisableAllocations();
// do something here #2.3
MemoryProfiler.Dump();
// do something here #3
MemoryProfiler.Dump();
if (MemoryProfiler.CanDetach)
MemoryProfiler.Detach();
PPS Это официальный ответ JetBrains:-)