Не удается подключиться к 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:-)

Другие вопросы по тегам