.net - C++/CLI WinForms: BeginInvoke Error -
i unable figure out reason error:
invoke or begininvoke cannot called on control until window handle has been created.
here (stripped) code:
private: delegate void mydelegate(object^ openfiledialog1); listview^ mydelegate; private: void import_links(object^ openfiledialog1) { mydelegate = (gcnew system::windows::forms::listview()); mydelegate->begininvoke( gcnew mydelegate( this, &form1::import_links ), openfiledialog1); //do work here } private: system::void import_linkclicked(system::object^ sender, system::windows::forms::linklabellinkclickedeventargs^ e) { openfiledialog^ openfiledialog1 = gcnew openfiledialog; if ( openfiledialog1->showdialog() == system::windows::forms::dialogresult::ok ) { thread^ importthread = gcnew thread(gcnew parameterizedthreadstart(this,&form1::import_links)); importthread->start(openfiledialog1); } }
please let me know solution.
mydelegate = (gcnew system::windows::forms::listview());
basic problems statement:
- it not delegate, listview object
- controls have strong association thread on created. creating control on worker thread never correct
- a control requires parent become visible , useful, doesn't have one
- a control requires thread run dispatcher loop can messages. such thread must call application::run(). worker thread doesn't
- the underlying window control created lazily, when needed become visible. since doesn't have parent , isn't visible, there wasn't need create window yet. won't have valid handle property, exception tells you
- begininvoke() ensures invoked code runs on thread owns control. since worker thread owns it, begininvoke() can never invoke thread
you have reference object owned correct thread. this
. correct code like:
void import_links(object^ openfiledialog1) { if (this->invokerequired) { this->begininvoke( gcnew mydelegate( this, &form1::import_links ), openfiledialog1); } else { //do work here } }
but note ultimate fallacy, created worker thread , only thing call this->begininvoke()
. takes fraction of microsecond. creating thread little work never useful.
refactor code, use backgroundworker. let dowork event handler only kind of things expensive, importing file. let runworkercompleted event only kind of things need happen on ui thread, such displaying result of import , hiding "i'm working on it" notification.
Comments
Post a Comment