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

2aad82720b49396fa84ba90edf53928e?d=identicon&s=25 Tetsuya YUASA (Guest)
on 2013-04-12 04:07
(Received via mailing list)
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?
3396e4a3df8a840faec520af8555a400?d=identicon&s=25 Mario Steele (Guest)
on 2013-04-15 21:29
(Received via mailing list)
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/r...
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:

>
>     evt_tool(Wx::ID_OPEN){|event| on_open_uri(event)}
>   end
>
> _______________________________________________
> 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
2aad82720b49396fa84ba90edf53928e?d=identicon&s=25 Tetsuya YUASA (Guest)
on 2013-04-16 03:58
(Received via mailing list)
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
This topic is locked and can not be replied to.