Asynchroniczna funkcja (std::async) nie działa na VS 2015.

0

Funckja:

std::async(std::launch::async, []() { g_game.getNewPing(); });

Działa bardzo dobrze na VS 2013 nie ma żadnego laga podczas pobierania pingu. Natomiast na VS 2015 już nie działa tak samo, jest tak jak by nie była wywolywana asynchronicznie.

Próbowałem różnych sposobów w każdej to samo. Kto wie czemu to nie działa tak jak powinno? Lub może ja coś źle robie?

2

Problem stanowi wartość zwracana std::future.
Nigdzie nie zapisujesz tej wartości, więc jest ona natychmiast niszczona.
A destruktor ten wywołuje wait, które czeka na wykonanie zadania z async.

Popraw tak:

auto result = std::async(std::launch::async, []() { g_game.getNewPing(); });

I zadbaj by czas życia result był dłuższy niż, czas potrzebny na wykonanie zadania na innym wątku.

0

W jaki sposób moge zadbać on ten czas życia async?
Jak poprawinie ma wyglądac moja funkcja?

0
ruth napisał(a):

W jaki sposób moge zadbać on ten czas życia async?
Jak poprawinie ma wyglądac moja funkcja?

std::async zwraca std::future, na którym wołasz metodę get() gdy będziesz chciałe pobrać wartość.

const int num = 5;
auto result = std::async(std::launch::async, [&] { return num + 5; });
std::cout << result.get();

W o get() można myśleć jako odpowiedniku join() z std::thread.

0

title

Nie mam pojęcia jak to zdebugować coś nie idzie.

1
ruth napisał(a):

W jaki sposób moge zadbać on ten czas życia async?
Jak poprawinie ma wyglądac moja funkcja?

Po prostu musisz gdzieś przenieść tą wartość (std::move), np do obiektu, który jest związany z wynikiem tej operacji.
Nie da się powiedzieć nic konkretniejszego, bo nic nie wiadomo na temat twojego kodu.

0
void Game::threadPing()
{
	if (m_realPingEvent) { m_realPingEvent->cancel(); m_realPingEvent = nullptr; }

	m_realPingEvent = g_dispatcher.scheduleEvent([=] { threadPing(); }, 3000);
	std::async(std::launch::async, []() { g_game.getNewPing(); });

}

int Game::getNewPing()
{
	unsigned long destAdress = inet_addr(m_worldHost.c_str());
	char SendData[32] = "Data Buffer";
	LPVOID ReplyBuffer = NULL;
	DWORD ReplySize = 0;
	DWORD dwRetVal = 0;

	if (destAdress == INADDR_NONE) {
		return pingTime = 0;
	}

	HANDLE hIcmpFile = IcmpCreateFile();
	if (hIcmpFile == INVALID_HANDLE_VALUE) {
		return pingTime = 0;
	}

	ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);
	ReplyBuffer = (VOID*)malloc(ReplySize);
	if (ReplyBuffer == NULL) {
		return pingTime = 0;
	}

	dwRetVal = IcmpSendEcho(hIcmpFile, destAdress, SendData, sizeof(SendData), NULL, ReplyBuffer, ReplySize, 5000);
	if (dwRetVal != 0) {
		PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
		return pingTime = pEchoReply->RoundTripTime;
	}
	return pingTime = 0;
}

Funckja g_game.getNewPing() ma byc wywolywana asynchronicznie poniewaz 'IcmpSendEcho' jest to funkcja blokujaca ktora czeka na ping i jest lekka scinka.
Dodam ze kod w takiej postaci działa asynchronicznie bez zadnego laga w visualu 2013 a w 2015 na ktorym mi zalezy juz nie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1