Замедляется ли выполнение потока, когда он выполняется внутри dll, а не в .exe?C#

Место общения программистов C#
Ответить
Anonymous
 Замедляется ли выполнение потока, когда он выполняется внутри dll, а не в .exe?

Сообщение Anonymous »

У меня есть проект Visual Studio 2022, в котором я создаю DLL C++. Эта DLL предоставляет функцию для запуска потоков.
Впоследствии у меня есть DLL C#, также в Visual Studio 2022, которая действует как оболочка. Он использует P/Invoke для включения всех функций из DLL C++, а затем предоставляет их как методы класса.
Когда я вызываю метод, предоставляемый моей DLL C#, для запуска потока из проекта используя C# DLL, поток работает с определенной скоростью (я отслеживаю скорость в Диспетчере задач -> Производительность -> Сеть, Кбит/с, поскольку потоки захватывают изображения с камеры и передают поток через HTTP).
Проблема в том, что эта скорость ниже по сравнению с тем, когда я изменяю проект C++ DLL с .dll на .exe, создаю тестовый основной файл и запускаю поток. (В данном случае она имеет более высокую скорость.)
Мне нужна моя DLL, чтобы обеспечить максимальную скорость, достигаемую при запуске из основной системы C++.
Если код потока под DLL в обоих случаях один и тот же, но в одном случае он выполняется в файле .dll, а в другом случае непосредственно в одном и том же исполняемом файле, может ли это повлиять? Как этого добиться?
Пример основного кода с правильной производительностью:

Код: Выделить всё

int main()
{
CCamFlir cam1 = CCamFlir(TCModel::A70, "10.0.0.102");

cam1.OnConnect();
cam1.OnSetLivePort(7001);
cam1.SetTransmission(1);
cam1.SetEmissivity(1);
cam1.SetAutoRange(false);
cam1.OnLoadPalette(TCPalette::IRON, 18, 40);
cam1.OnSetZoom(1.0, 0, 0);

cam1.setCamBeforeStream();
cam1.StartThermalStream();

cam1.OnSetLiveThreadFrequency(30);
cam1.OnSetAcquisitionTCFrameRate(FrameRateAvailable::HZ30);

cam1.OnDrawRoiSquare(6, "", 50, 50, 255, 0, 0, 255, 255, 255, FontType::FONT_HERSHEY_PLAIN,
2, 50, 50, 55, 55);

cam1.StartHTTPServer(60000);
int conta = 0;
while (true)
{

//if (cv::waitKey(33) == 27) // Exit when ESC is pressed
//  break;
//std::this_thread::sleep_for(std::chrono::milliseconds(1000));
//conta++;
//if (conta == 10) {
//  cam1.OnSetRange(LOW);
//}

}
return 0;

}
Код медленного потока:

Код: Выделить всё

void UpdateCurrentFrame(CCamFlir* camInstance)
{
try
{
camInstance->isTerminateUpdateCurrentFrameThread = false;
high_resolution_clock::time_point start;
high_resolution_clock::time_point end;
int frames = 0;

high_resolution_clock::time_point fps_timer = high_resolution_clock::now();
camInstance->m_rawImageLive = Image::Create();
std::atomic shouldTerminate(false);

while (!camInstance->m_terminate)
{
start = high_resolution_clock::now();
high_resolution_clock::time_point iteration_start = high_resolution_clock::now();

try
{
camInstance->m_rawImageReceive = camInstance->m_cam->GetNextImage();
if (!camInstance->m_rawImageReceive->IsIncomplete() || camInstance->m_rawImageReceive->GetImageStatus() == 0)
{
camInstance->m_rawImageLive->DeepCopy(camInstance->m_rawImageReceive);
}

}
catch (std::exception& ex)
{
std::string e = ex.what();
camInstance->m_status = DISCONNECTED;
}
end = high_resolution_clock::now();

long duration = duration_cast(end - start).count();
std::chrono::milliseconds durataMilliseconds(duration);
camInstance->m_iterationTime = durataMilliseconds;

frames++;

camInstance->m_rawImageReceive->Release();

auto elapsed = duration_cast(end - fps_timer).count();

if (elapsed >= 1) {
camInstance->m_effectiveFrameRate = static_cast(frames) / elapsed;

fps_timer = high_resolution_clock::now();
frames = 0;
}

}
camInstance->isTerminateUpdateCurrentFrameThread = true;

}
catch (const std::exception& ex)
{
std::string eccezione = ex.what();
camInstance->m_status = DISCONNECTED;
camInstance->isTerminateUpdateCurrentFrameThread = true;

}
}

начало темы:

Код: Выделить всё

bool CCamFlir::StartThermalStream()
{
try
{
m_cam->BeginAcquisition();
if (m_getNextImageThread.joinable())
m_getNextImageThread.join();
m_getNextImageThread = std::thread(UpdateCurrentFrame, this);

if (m_getLiveImage.joinable())
m_getLiveImage.join();
m_getLiveImage = std::thread(GetLiveImage, this);

if (m_updateROIValue.joinable())
try
{
m_updateROIValue.join();

}
catch (const std::exception& ex)
{
std::cout StartThermalStream(); }
Класс C#, представленный из dll C#

Код: Выделить всё

[DllImport("lib\\DriverFlir.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool CamFlir_StartThermalStream(IntPtr cam);

private IntPtr PtrCam { get; set; }

public void StartStream()
{
CamFlir_SetCamBeforeStream(PtrCam);
CamFlir_StartThermalStream(PtrCam);
}

Основной C#, с проблемой эффективности:

Код: Выделить всё

namespace CameraFlir
{
public class Program
{
public static void Main(string[] args)
{
string ip = "10.0.0.102";
byte[] byteArray = Encoding.UTF8.GetBytes(ip);

CameraFlir cam1 = new CameraFlir(DriverFlir.TCModel.A70, byteArray);
cam1.Connect();
cam1.Transmission = 1;
cam1.Emissivity = 1;
cam1.SetAutoRange(true);
cam1.SetPalette(DriverFlir.TCPalette.IRON);
cam1.SetZoom(1, 0, 0);

cam1.StartStream();
cam1.LiveFps = 30;
cam1.AcqusitionTCFrequency = DriverFlir.FrameRateAvailable.HZ30;

cam1.StartHTTPServer(65000);

while (true)
{

}
}
}
}
Производительность сети (правильная, с точки зрения количества изображений, снятых с камеры в секунду) при выполнении непосредственно на C++:
Низкая производительность сети при вызове из C#
Я ожидаю, что на скорость влияет изменение языка вызова, но после запуска потока разве сам поток не должен быть таким же? Разве он не должен знать о вызывающем объекте и функционировать таким же образом?

Подробнее здесь: https://stackoverflow.com/questions/786 ... d-of-a-exe
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»