By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,996 Members | 1,179 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,996 IT Pros & Developers. It's quick & easy.

Asynchronous call, but not really

P: n/a
Hello,

I'm working on an application that grabs some data from the web via
HttpWebRequest. I'm using a local objects method to get the data, but
the problem is that my form doesn't load until this method has
finished what it's doing.. which takes about 10-15 seconds. Here is
what I have:

Using System.Threading;

public class MyClass{
private MyObject mynewobject= new MyObject();
...
private delegate void GetDataDelegate(string url);

public MyClass(){
InitalizeComponent();
GetWebData(); // <- form isn't visible until after this
returns
this.lblStatus.Text = "finished";
}

private GetWebData(){
GetDataDelegate gdd = new
GetDataDelegate(mynewobject.RetrieveData);

// Initiate the asynchronous call
IAsyncResult ar = gdd.BeginInvoke("http://www.whatever.com/
file.txt", null, null);
Thread.Sleep(0);
this.lblStatus.Text = "getting data";
mld.EndInvoke(ar);
}
}

Again, what's happening is that the application starts, but I get no
visual cue that it has started, until after the GetWebData() call has
returned, sometimes it takes up to 30 seconds. I need the form and
components to be loaded first, but I'd also like to be pulling data as
soon as the program runs. What am I doing wrong? Thanks
Dec 7 '07 #1
Share this Question
Share on Google+
5 Replies


P: n/a
On Dec 7, 4:25 pm, tcomer <tco...@gmail.comwrote:

<snip>
Again, what's happening is that the application starts, but I get no
visual cue that it has started, until after the GetWebData() call has
returned, sometimes it takes up to 30 seconds. I need the form and
components to be loaded first, but I'd also like to be pulling data as
soon as the program runs. What am I doing wrong? Thanks
You're calling EndInvoke, which will wait until GetData returns. So
yes, you're doing things asynchronously - but you're not actually
achieving any benefits.

Instead of calling EndInvoke, specify a callback in the call to
BeginInvoke so that your UI thread will be free while the web request
is fetching data.

Jon
Dec 7 '07 #2

P: n/a
Well, technically, the form doesn't show until after the constructor is
called. It's just that what you do after the call to GetWebData is so quick
that it isn't perceptable (there are also some other calls that are made
under the covers).

As for what is causing your problem, you are calling the request
asynchronously, but you are then calling EndInvoke right after. EndInvoke
will block until the call is complete.

The call to Sleep doesn't do anything useful in this case, btw.

What you need to do is pass a delegate to the BeginInvoke method which
will get executed when the call is complete. Then call EndInvoke in that
method, and you will then be able to access your data.

You would have to make sure that if you are updating the UI though, you
are doing so by calling Invoke on the control, as your callback will not be
executed on the UI thread.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"tcomer" <tc****@gmail.comwrote in message
news:30**********************************@i29g2000 prf.googlegroups.com...
Hello,

I'm working on an application that grabs some data from the web via
HttpWebRequest. I'm using a local objects method to get the data, but
the problem is that my form doesn't load until this method has
finished what it's doing.. which takes about 10-15 seconds. Here is
what I have:

Using System.Threading;

public class MyClass{
private MyObject mynewobject= new MyObject();
...
private delegate void GetDataDelegate(string url);

public MyClass(){
InitalizeComponent();
GetWebData(); // <- form isn't visible until after this
returns
this.lblStatus.Text = "finished";
}

private GetWebData(){
GetDataDelegate gdd = new
GetDataDelegate(mynewobject.RetrieveData);

// Initiate the asynchronous call
IAsyncResult ar = gdd.BeginInvoke("http://www.whatever.com/
file.txt", null, null);
Thread.Sleep(0);
this.lblStatus.Text = "getting data";
mld.EndInvoke(ar);
}
}

Again, what's happening is that the application starts, but I get no
visual cue that it has started, until after the GetWebData() call has
returned, sometimes it takes up to 30 seconds. I need the form and
components to be loaded first, but I'd also like to be pulling data as
soon as the program runs. What am I doing wrong? Thanks

Dec 7 '07 #3

P: n/a
You're calling EndInvoke, which will wait until GetData returns. So
yes, you're doing things asynchronously - but you're not actually
achieving any benefits.

Instead of calling EndInvoke, specify a callback in the call to
BeginInvoke so that your UI thread will be free while the web request
is fetching data.

Jon
That makes complete sense now that you pointed it out, funny how that
works :) Exactly what I was looking for, thanks a lot.

Dec 7 '07 #4

P: n/a
Thanks for the help.. I think I've got it figured out.

Although, I do have one other question. Hopefully someone could just
point me in the right direction.

Within the asynchronous call, I'd like to start one other thread that
will Start, process a chunk of data, update the datagrid and then
return to get another chunk of data(I'm not going thread-happy here,
trust me). Basically, when the data is being retrieved.. my datagrid
should be updating as the application receives the data. Could someone
please point me in the right direction? I'm a newbie when it comes to
threading.. sorta.
Dec 7 '07 #5

P: n/a
On Fri, 07 Dec 2007 10:50:54 -0800, tcomer <tc****@gmail.comwrote:
Within the asynchronous call, I'd like to start one other thread that
will Start, process a chunk of data, update the datagrid and then
return to get another chunk of data(I'm not going thread-happy here,
trust me). Basically, when the data is being retrieved.. my datagrid
should be updating as the application receives the data. Could someone
please point me in the right direction? I'm a newbie when it comes to
threading.. sorta.
As Nicholas says, you'll need to use Control.Invoke() to actually update
your user interface. Other than that, it's simply a matter of organizing
the processing logic so that it does things when you want it to.

On that topic, while you're not specific about how you're doing your i/o,
it's likely at some point you're using a built-in class that already has
an asynchronous API. If so, it'd be my recommendation that you forget
doing any threading yourself, whether explicitly starting a new thread or
using the thread pool via the Delegate.BeginInvoke() method. Instead, it
would be better to just write the data-handling class so that it's using
the asynchronous API on the i/o class you're using. You can code it to
call the "Begin..." to start retrieval of a "chunk of data", then when
that chunk completes you update your UI to reflect the data and start
another chunk, again with a call to "Begin...".

IMHO, this is much cleaner than creating a bunch of threads and managing
it yourself. This is especially true given the apparent flow of data
through your logic that you've described here.

Pete

Dec 7 '07 #6

This discussion thread is closed

Replies have been disabled for this discussion.