Tôi đã tìm thấy rằng tăng :: signal2 sử dụng loại bỏ một cách lười biếng các khe được kết nối, điều này làm cho việc sử dụng các kết nối trở nên khó khăn như điều gì đó quản lý thời gian sống của các đối tượng. Tôi đang tìm một cách để buộc các khe bị xóa trực tiếp khi bị ngắt kết nối. Bất kỳ ý tưởng về cách làm việc xung quanh vấn đề bằng cách thiết kế mã của tôi khác nhau cũng được đánh giá cao!Bắt buộc xóa khe trong tăng :: signal2
Đây là kịch bản của tôi: Tôi có một lớp học chỉ huy chịu trách nhiệm về thực hiện một cái gì đó mà cần có thời gian không đồng bộ, tìm kiếm một cái gì đó như thế này (giản thể):
class ActualWorker {
public:
boost::signals2<void()> OnWorkComplete;
};
class Command : boost::enable_shared_from_this<Command> {
public:
...
void Execute() {
m_WorkerConnection = m_MyWorker.OnWorkDone.connect(boost::bind(&Command::Handle_OnWorkComplete, shared_from_this());
// launch asynchronous work here and return
}
boost::signals2<void()> OnComplete;
private:
void Handle_OnWorkComplete() {
// get a shared_ptr to ourselves to make sure that we live through
// this function but don't keep ourselves alive if an exception occurs.
shared_ptr<Command> me = shared_from_this();
// Disconnect from the signal, ideally deleting the slot object
m_WorkerConnection.disconnect();
OnComplete();
// the shared_ptr now goes out of scope, ideally deleting this
}
ActualWorker m_MyWorker;
boost::signals2::connection m_WorkerConnection;
};
Lớp được gọi về như thế này:
...
boost::shared_ptr<Command> cmd(new Command);
cmd->OnComplete.connect(foo);
cmd->Execute();
// now go do something else, forget all about the cmd variable etcetera.
Lớp Lệnh giữ bản thân còn sống bằng cách nhận shared_ptr cho chính nó, nó được gắn với tín hiệu ActualWorker bằng cách sử dụng boost :: bind.
Khi nhân viên hoàn tất, trình xử lý trong Lệnh được gọi. Bây giờ, vì tôi muốn đối tượng Command bị phá hủy, tôi ngắt kết nối từ tín hiệu như có thể thấy trong đoạn mã trên. Vấn đề là đối tượng khe thực sự không bị xóa khi bị ngắt kết nối, nó chỉ được đánh dấu là không hợp lệ và sau đó bị xóa sau đó. Điều này lần lượt xuất hiện để phụ thuộc vào tín hiệu để bắn một lần nữa, mà nó không làm trong trường hợp của tôi, dẫn đến khe không bao giờ hết hạn. Đối tượng bind :: bind do đó không bao giờ đi ra khỏi phạm vi, giữ một shared_ptr với đối tượng của tôi mà sẽ không bao giờ bị xóa.
Tôi có thể giải quyết vấn đề này bằng cách sử dụng con trỏ này thay vì shared_ptr và sau đó giữ đối tượng của tôi còn sống bằng cách sử dụng thành viên shared_ptr mà sau đó tôi phát hành trong hàm xử lý, nhưng nó làm cho thiết kế cảm thấy hơi phức tạp. Có cách nào để buộc signal2 xóa khe khi ngắt kết nối không? Hoặc có cái gì khác tôi có thể làm để đơn giản hóa thiết kế?
Mọi nhận xét đều được đánh giá cao!
Ngắt kết nối ở phần cuối của thực hiện chức năng đánh bại mục đích của việc kết nối ở tất cả - tức là tôi sẽ không nhận được một cuộc gọi lại khi không đồng bộ công việc đã hoàn thành. Vì vậy, đề xuất của bạn không thực sự khả thi. – villintehaspam