I want to use Open-URI::open in a Thread. But with this code freeze the window when I push toolbar button. require "open-uri" require ''wx'' class MyApp < Wx::App def on_init MyFrame.new.show end end class MyFrame < Wx::Frame def initialize super(nil, -1, "TreeCtrl,Thread,Open-URI") toolbar = Wx::ToolBar.new(self) top_sizer = Wx::BoxSizer.new(Wx::VERTICAL) treectrl = Wx::TreeCtrl.new(self) top_sizer.add(treectrl) toolbar.add_tool(Wx::ID_OPEN, ''Open'', Wx::ArtProvider.bitmap(Wx::ART_GO_HOME), ''Open URI'') toolbar.realize evt_tool(Wx::ID_OPEN){|event| on_open_uri(event)} self.set_tool_bar(toolbar) Wx::Timer.every(100){ sleep 0.05 } end def on_open_uri(event) Thread.new{ open("http://google.com"){|f| p content = f.read } } end end MyApp.new.main_loop If I comment out following two lines, it works fine. # treectrl = Wx::TreeCtrl.new(self) # top_sizer.add(treectrl) And without "Thread" this program runs well. I would like to add that if I don''t use Open::URI.open in the Thread, no error occurs. This behavior seems strange to me. Why is this happening? How can I use Open-URI in a Thread if I want to use the TreeCtrl? -- Tetsuya _______________________________________________ wxruby-users mailing list wxruby-users@rubyforge.org http://rubyforge.org/mailman/listinfo/wxruby-users
Mario Steele
2013-Apr-15 19:13 UTC
Re: Can''t use open-uri in a Thread if there are treectrl
Hello Tetsuya, First of all, when dealing with Ruby Threads, you need to have a Thread.pass in your code, in order to allow Ruby''s Green Threads to operate, and get CPU time, outside of the Main GUI Thread. You can do this, by putting in your MyApp#on_init method: class MyApp < Wx::App def on_init Wx::Timer.every(500) { Thread.pass } MyFrame.new.show end end This will give you some more responsiveness with Green Threads, and OpenURI. The other thing you should look at, is OpenURI''s methods for callbacks options in Open, more specifically http://ruby-doc.org/stdlib-1.9.3/libdoc/open-uri/rdoc/OpenURI/OpenRead.html With the options for :content_length_proc and :progress_proc, these options will give you the ability to get call-backs after the header is received for how much is about to be downloaded with :content_length_proc, and as the download occurs, it will return the total downloaded bytes that OpenURI has received. This is generally useful for Progress Bars, and such. hth, Mario On Thu, Apr 11, 2013 at 9:44 PM, Tetsuya YUASA <tetsuya@ironsand.net> wrote:> I want to use Open-URI::open in a Thread. > But with this code freeze the window when I push toolbar button. > > require "open-uri" > require ''wx'' > class MyApp < Wx::App > def on_init > MyFrame.new.show > end > end > > class MyFrame < Wx::Frame > def initialize > super(nil, -1, "TreeCtrl,Thread,Open-URI") > toolbar = Wx::ToolBar.new(self) > top_sizer = Wx::BoxSizer.new(Wx::VERTICAL) > treectrl = Wx::TreeCtrl.new(self) > top_sizer.add(treectrl) > toolbar.add_tool(Wx::ID_OPEN, ''Open'', > Wx::ArtProvider.bitmap(Wx::ART_GO_HOME), ''Open URI'') > toolbar.realize > evt_tool(Wx::ID_OPEN){|event| on_open_uri(event)} > self.set_tool_bar(toolbar) > Wx::Timer.every(100){ sleep 0.05 } > end > > def on_open_uri(event) > Thread.new{ > open("http://google.com"){|f| > p content = f.read > } > } > end > end > > MyApp.new.main_loop > > If I comment out following two lines, it works fine. > > # treectrl = Wx::TreeCtrl.new(self) > # top_sizer.add(treectrl) > > And without "Thread" this program runs well. > > I would like to add that if I don''t use Open::URI.open in the Thread, no > error occurs. > > This behavior seems strange to me. > Why is this happening? > How can I use Open-URI in a Thread if I want to use the TreeCtrl? > > -- > Tetsuya > > _______________________________________________ > wxruby-users mailing list > wxruby-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/wxruby-users >-- Mario Steele Fleet Captain CO - Geo 99 CO - USS T''hy''la XO - Diplomatic Corps - Second Life http://www.iftcommand.com/chapters/thyla/ http://www.trekfederation.com _______________________________________________ wxruby-users mailing list wxruby-users@rubyforge.org http://rubyforge.org/mailman/listinfo/wxruby-users
Tetsuya YUASA
2013-Apr-16 01:05 UTC
Re: Can''t use open-uri in a Thread if there are treectrl
Hello Mario, Thank you for your advice! As you say, I added the following line into the script. Wx::Timer.every(500) { Thread.pass } But the Window still freeze if I press the button. In the last message, I forgot to write my environment. I''m using wxruby-ruby19 (2.0.1 x86-mingw32), and ruby 1.9.3p125 (2012-02-16) [i386-mingw32] Is there some other way to solve the problem? -- Tetsuya Yuasa On Tue, Apr 16, 2013 at 4:13 AM, Mario Steele <mario@ruby-im.net> wrote:> Hello Tetsuya, > > First of all, when dealing with Ruby Threads, you need to have a > Thread.pass in your code, in order to allow Ruby''s Green Threads to > operate, and get CPU time, outside of the Main GUI Thread. > > You can do this, by putting in your MyApp#on_init method: > > class MyApp < Wx::App > def on_init > Wx::Timer.every(500) { Thread.pass } > MyFrame.new.show > end > end > > This will give you some more responsiveness with Green Threads, and > OpenURI. The other thing you should look at, is OpenURI''s methods for > callbacks options in Open, more specifically > http://ruby-doc.org/stdlib-1.9.3/libdoc/open-uri/rdoc/OpenURI/OpenRead.html With > the options for :content_length_proc and :progress_proc, these options will > give you the ability to get call-backs after the header is received for how > much is about to be downloaded with :content_length_proc, and as the > download occurs, it will return the total downloaded bytes that OpenURI has > received. This is generally useful for Progress Bars, and such. > > > hth, > > Mario > > > On Thu, Apr 11, 2013 at 9:44 PM, Tetsuya YUASA <tetsuya@ironsand.net>wrote: > >> I want to use Open-URI::open in a Thread. >> But with this code freeze the window when I push toolbar button. >> >> require "open-uri" >> require ''wx'' >> class MyApp < Wx::App >> def on_init >> MyFrame.new.show >> end >> end >> >> class MyFrame < Wx::Frame >> def initialize >> super(nil, -1, "TreeCtrl,Thread,Open-URI") >> toolbar = Wx::ToolBar.new(self) >> top_sizer = Wx::BoxSizer.new(Wx::VERTICAL) >> treectrl = Wx::TreeCtrl.new(self) >> top_sizer.add(treectrl) >> toolbar.add_tool(Wx::ID_OPEN, ''Open'', >> Wx::ArtProvider.bitmap(Wx::ART_GO_HOME), ''Open URI'') >> toolbar.realize >> evt_tool(Wx::ID_OPEN){|event| on_open_uri(event)} >> self.set_tool_bar(toolbar) >> Wx::Timer.every(100){ sleep 0.05 } >> end >> >> def on_open_uri(event) >> Thread.new{ >> open("http://google.com"){|f| >> p content = f.read >> } >> } >> end >> end >> >> MyApp.new.main_loop >> >> If I comment out following two lines, it works fine. >> >> # treectrl = Wx::TreeCtrl.new(self) >> # top_sizer.add(treectrl) >> >> And without "Thread" this program runs well. >> >> I would like to add that if I don''t use Open::URI.open in the Thread, no >> error occurs. >> >> This behavior seems strange to me. >> Why is this happening? >> How can I use Open-URI in a Thread if I want to use the TreeCtrl? >> >> -- >> Tetsuya >> >> _______________________________________________ >> wxruby-users mailing list >> wxruby-users@rubyforge.org >> http://rubyforge.org/mailman/listinfo/wxruby-users >> > > > > -- > Mario Steele > Fleet Captain > CO - Geo 99 > CO - USS T''hy''la > XO - Diplomatic Corps - Second Life > http://www.iftcommand.com/chapters/thyla/ > http://www.trekfederation.com > > _______________________________________________ > wxruby-users mailing list > wxruby-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/wxruby-users >_______________________________________________ wxruby-users mailing list wxruby-users@rubyforge.org http://rubyforge.org/mailman/listinfo/wxruby-users