我正在C++框架中工作,主要是在C++ 11之前編寫的,它允許我們將事件從一個線程引發到另一個線程(假設接收線程正在運行事件隊列,所以它主要用於從輔助線程向主UI線程中引發事件)。在不同線程中調用std :: function
目前,完成這一任務的代碼非常冗長 - 它需要我們定義兩個類:
- 包含我們想要傳遞的任何信息事件類。
- 在接收線程中處理事件的偵聽器類。
我們最近轉移到了C++ 11/14,並且一直致力於更新我們的許多代碼以使用智能指針,標準容器和lambda表達式。我想寫一個通用類,允許我發送一個lambda在不同的線程中運行。喜歡的東西:
mBoundary = make_unique<ThreadBoundary>([](int value) { doSomething(value); });
mBoundary->callInMainThread(47);
ThreadBoundary boundary2([](std::string value) { displayString(value); });
boundary2.callInMainThreadWait("Show this string to the user");
作爲一個初步的嘗試,我現在有一個拉姆達不帶任何參數,建立在目前的框架功能之上這方面的工作(省略錯誤檢查,清理等) :
class ThreadBoundary
{
public:
ThreadBoundary(std::function<void()> function):mFunction(function)
{
mListener = make_shared<ThreadBoundaryListener>();
cApplication::addThreadBoundaryListener(mListener);
}
void callInMainThread()
{
cApplication::fireEventInMainThread(new ThreadBoundaryEvent(mFunction));
}
class ThreadBoundaryEvent:public FrameworkThreadBoundaryEvent
{
public:
ThreadBoundaryEvent(std::function<void()> function)
{
mFunction = function;
}
void call() { mFunction(); }
private:
std::function<void()> mFunction;
};
class ThreadBoundaryListener:public FrameworkThreadBoundaryListener
{
public:
ThreadBoundaryListener() {}
void handleEvent(const FrameworkThreadBoundaryEvent* event)
{
dynamic_cast<const ThreadBoundaryEvent*>(event)->call();
}
};
private:
shared_ptr<ThreadBoundaryListener> mListener;
std::function<void()> mFunction;
};
這讓我不過火「一次性」事件給主線程,而不能沿參數發送給它的功能是相當有限。
我想讓這個類使用可變參數模板,以便我可以傳遞任何東西給callInMainThread
函數。但是,我一直無法弄清楚如何將參數包存儲在事件中,並將它傳遞給call()
中的函數。所以我的問題是:
- 是否有可能存儲參數包,然後傳遞給std :: function?
- 有沒有更好的方法來做到這一點在c + + 11/14,不需要大量的重新設計?我們的框架目前正在封裝OS功能來實現這一點(即在Windows上它使用SendMessage vs OS X中的performSelectorOnMainThread)。
出於某種原因,我認爲有些情況下,這將無法正常工作,但目前我無法做出任何決定。所以我想我會用你的解決方案,謝謝! – Runt8