Can't use open-uri in a Thread if there are treectrl


#1

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?


#2

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 removed_email_address@domain.invalid
wrote:

evt_tool(Wx::ID_OPEN){|event| on_open_uri(event)}

end


wxruby-users mailing list
removed_email_address@domain.invalid
http://rubyforge.org/mailman/listinfo/wxruby-users


Mario S.
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


#3

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