|
well, here is the new log:
<br />
17:13.796 [000A] Start DownloadFile-Thread<br />
17:13.796 [000A] Start DownloadFile-Thread<br />
17:13.796 [000C] Do the webrequest<br />
17:13.796 [000A] Start DownloadFile-Thread<br />
17:13.796 [000D] Do the webrequest<br />
17:13.796 [000D] End the webrequest<br />
17:13.828 [000D] Retrieve the response from the server<br />
17:13.828 [000A] Start DownloadFile-Thread<br />
17:13.796 [000C] End the webrequest<br />
17:13.843 [000C] Retrieve the response from the server<br />
17:13.828 [000E] Do the webrequest<br />
17:13.843 [000F] Do the webrequest<br />
17:13.859 [000E] End the webrequest<br />
17:13.859 [000E] Retrieve the response from the server<br />
17:13.859 [000F] End the webrequest<br />
17:13.859 [000F] Retrieve the response from the server<br />
17:14.203 [000D] After Retrieve the response from the server<br />
17:14.203 [000D] Get the response-stream<br />
17:14.203 [000D] After Get the response-stream<br />
17:14.218 [000D] Start while-loop<br />
17:18.687 [000D] End while-loop<br />
The thread 0x9c4 has exited with code 0 (0x0).<br />
17:18.859 [000C] After Retrieve the response from the server<br />
17:18.859 [000C] Get the response-stream<br />
17:18.859 [000C] After Get the response-stream<br />
17:18.875 [000C] Start while-loop<br />
17:22.109 [000C] End while-loop<br />
17:22.109 [000F] After Retrieve the response from the server<br />
The thread 0x9c0 has exited with code 0 (0x0).<br />
17:22.125 [000F] Get the response-stream<br />
17:22.125 [000F] After Get the response-stream<br />
17:22.125 [000F] Start while-loop<br />
17:25.265 [000F] End while-loop<br />
The thread 0xf04 has exited with code 0 (0x0).<br />
The program '[4024] DownloadManager.vshost.exe: Managed' has exited with code 0 (0x0).<br />
and StartDownload:
<br />
private void StartDownload()<br />
{<br />
try<br />
{<br />
webRequest = (HttpWebRequest)WebRequest.Create(dowloadUrl);<br />
if (!dowloadProxy.Equals(string.Empty))<br />
webRequest.Proxy = new WebProxy(dowloadProxy);<br />
<br />
log("Do the webrequest");<br />
if(endOffset>0)<br />
webRequest.AddRange(startOffset, endOffset);<br />
else<br />
webRequest.AddRange(startOffset);<br />
log("End the webrequest");<br />
<br />
webRequest.Credentials = CredentialCache.DefaultCredentials;<br />
log("Retrieve the response from the server");<br />
webResponse = (HttpWebResponse)webRequest.GetResponse();<br />
log("After Retrieve the response from the server");<br />
fileSize = webResponse.ContentLength;<br />
log("Get the response-stream");<br />
strResponse = webResponse.GetResponseStream();<br />
log("After Get the response-stream");<br />
<br />
strLocal = new FileStream(outFile, FileMode.Create, FileAccess.Write, FileShare.Write);<br />
<br />
int bytesSize;<br />
byte[] downBuffer = new byte[2048];<br />
<br />
downStart = DateTime.Now;<br />
<br />
log("Start while-loop");<br />
while ((bytesSize = strResponse.Read(downBuffer, 0, downBuffer.Length)) > 0)<br />
{<br />
strLocal.Write(downBuffer, 0, bytesSize);<br />
}<br />
log("End while-loop");<br />
}<br />
catch (Exception e)<br />
{<br />
lastError = e;<br />
RaiseDownloadError(e);<br />
}<br />
finally<br />
{<br />
if (strResponse != null) strResponse.Close();<br />
if (strLocal != null) strLocal.Close();<br />
}<br />
} <br />
That didn't seem to make that much of a difference and the threads still runs one after the other.
You can have a look at the whole thing here: http://johanmartensson.se/downloadmanager.rar
It's quite messy, but you'll get the idea
|
|
|
|
|
Well, tytping while I read it, it is not fully sequential; for instance we get several
"Retrieve the response from the server" close to each other (that is fine), but the
while loops are not intermingling.
So its in between those two that it starts to go wrong (i.e. sequential).
I'll study it some more...
|
|
|
|
|
OK, this is the relevant part of the log:
17:13.796 [000C] Do the webrequest
17:13.796 [000D] Do the webrequest
17:13.796 [000D] End the webrequest
17:13.828 [000D] Retrieve the response from the server --------------- good
17:13.796 [000C] End the webrequest
17:13.843 [000C] Retrieve the response from the server --------------- good
17:13.828 [000E] Do the webrequest
17:13.843 [000F] Do the webrequest
17:13.859 [000E] End the webrequest
17:13.859 [000E] Retrieve the response from the server --------------- good
17:13.859 [000F] End the webrequest
17:13.859 [000F] Retrieve the response from the server --------------- good
17:14.203 [000D] After Retrieve the response from the server ============ good
17:14.203 [000D] Get the response-stream
17:14.203 [000D] After Get the response-stream
17:14.218 [000D] Start while-loop
17:18.687 [000D] End while-loop
The thread 0x9c4 has exited with code 0 (0x0).
17:18.859 [000C] After Retrieve the response from the server ============ this one is late
Observations:
- the while loop takes much longer than everything else; that's good, it tells us we
could make smaller read requests without much penalty if we would choose to do so,
and/or more GetResponse calls.
- the first thing to show after one of the threads are finished, is the line
"... After Retrieve the response from the server " so that is the one we would really like
to get sooner, much sooner.
The relevant code is:
log("Retrieve the response from the server");
webResponse = (HttpWebResponse)webRequest.GetResponse();
log("After Retrieve the response from the server");
so it is the GetResponse that fails to return on time. Why would that be ?
It seems like one strResponse must be closed before another one can return from GetResponse.
That is to say the other threads also issued their GetResponse() and are just waiting;
I would accept they must wait until the first GetResponse returns; but seeing them wait
until the while loop and close are done puzzles me (I am not a network expert tho).
I noticed the existence of BeginGetResponse and EndGetResponse, that support asynchronous
operation. Now asynchronous means the thread can continue and go on do other things;
what we dont know is, if four threads issue BeginGetResponse, will they intermingle any
better than what we have now. I think you will have to read up or Google on these.
Current summary:
- GUI update is not the cause of the problem
- we established 4 threads are starting download concurrently
- but they fall in sequential mode as soon as a GetResponse gets executed
Additional reading (I just googled "HttpRequest GetResponse concurrent" and browsed some
of the hits, without really reading/studying it all):
http://msdn.microsoft.com/msdnmag/issues/04/12/NETMatters/[^] explains .NET 1.1 needs ThreadPool threads to execute GetResponse, and
may throw a no-thread-available-exception. You are running >= 2.0 are you ?
http://discuss.joelonsoftware.com/default.asp?dotnet.12.519394[^] explains the first ever GetResponse takes very long,
so you might want to do a dummy long before you really need one. You could check by
making your program trying the same download twice and watch the timestamps.
http://www.feedshow.com/show_items-feed=04ba4cfa290afeb01d0b72f898516048[^] gives bad
news about GC temporarily disabled since threads sometimes can not be suspended.
GetResponse Performance Issue (first-time call)[^]
This one implies some good news:
http://episteme.arstechnica.com/groupee/forums/a/tpc/f/6330927813/m/969001547731[^] "My understanding of HttpWebRequest is that if you use .GetResponse instead of .BeginGetResponse then it doesn't matter how many threads you're running, the calls will block each other." Although it does not sound optimistic all the way !
Possible routes from here:
- you might stick with GetResponse and try to do much larger Reads (say 128KB or 1MB),
and do a GetResponse-Read-Close cycle; loop over these in each of the four threads.
Trick is the local stuff (writing to stream, GUI update) now happen after the close,
so another thread can get results from GetResponse in the mean time.
- try with async stuff (Begin/End); warning: MSDN states its an all or nothing choice
(all sync or all async). You may want to read this first.[^]
I hope this helps you enough to rethink and come up with a new, revised class.
Hope you keep us informed (and/or maybe write an article once solved).
|
|
|
|
|
Thanks for all your help, it's been very useful.
I will now read up on the GetResponse and see what I come up with.
I'll keep you posted and I will try to write an article in the end.
|
|
|
|
|
|
The problem was with the ConnectionLimit on the webRequest.
So adding this line did the trick, where connectionLimit is an int:
webRequest.ServicePoint.ConnectionLimit = connectionLimit;
|
|
|
|
|
Thanks, and good luck. How fast is your download now (in KB/s or MB/s) with 1 and with
4 threads, so was it all worth it ?
|
|
|
|
|
When I download a file that I get around 300KB/s on one thread, I get around 850KB/s on three threads.
So, yes I think it was worth it and besides, since I wanted to do it and it didn't work, I just had to figure it out, we can't let us be beaten by some code, can we?
|
|
|
|
|
|
Hi,
I have a problem binding a DataSource object to multiple TextBoxes on the same form. It seems that the TextBox object is not dynamic, it doesn't change its Text value if the datasource changes.
So I did a small experiment to prove this. In a form I initialize three controls and a Members object(derived from a DataSet): Note also that mem[0] returns a DataTable.
Members mem = new Members();
mem.ReadRange(1004, 1004);
binding = new BindingSource(mem[0], null);
textBox1.DataBindings.Add("Text", binding, "FirstName");
textBox2.DataBindings.Add("Text", binding, "FirstName");
dataGridView1.DataSource = mem[0];
Here if I type data in the TextBox1, the datagrid reacts and shows me the modified data on Leave, but TextBox2 doesn't react.
Same reaction for TextBox2.
If I modify data in the DataGrid's column, none of the Textboxes react until BindingSource.Position changes.
So I need a way to make the two text boxes to look at the state of the BindingSource adn detect any changes and react to it
I tried also to detect events on BindingSource and BindingSource.CurrencyManager and nothig fires when leaving one of the TextBoxes.
Really
|
|
|
|
|
Replying to myself but any better suggestions are welcomed
I used the .Leave event on the TextBoxes to force a BindinSource.EdnEdit();
But now I have to manipulate every control individually.
Is there a better wayto do this ?
Thanks in advance for any input
|
|
|
|
|
I didn't comprehend your sample completly but some basics about binding:
- values in bound controls get updated when
+ BindingSource.ResetCurrentItem is called
+ a PropertyChanged event on the bound object is fired (see INotifyPropertyChanged)
- Leave on TextBox does not lead to a BindingSource.EndEdit, but EndEdit will cause validation on the control without losing focus.
And as a last thought: binding is a pain when you have to program UIs with controls that depend on each other - I's suggest using a variation of the MVP (mode view presenter) pattern (Presenter First or Passive View are my personal favourites )
Hope this helps a bit!
-^-^-^-^-^-
no risk no funk
|
|
|
|
|
Your Model View Presenter interested me, I have no intention on implementing this for my current project but I will definitely look into this for the future.
I didn't find a lot of literature on the subject, it would be of everybody's interest if you had reading suggestion (specifically a good book) on the subject of MVP model.
Thanks a lot for your input
|
|
|
|
|
Unfortunately, there isn't too much in the internet about this topic. Either it's very abstract and difficult to transform in real world applications or it's a very simple description of MVP that lacks any information about all the surroundings.
There are also quite a few different approaches (classic MVP, Presenter First, Passive View, ...).
Therefore, I can't point you to a good article about MVP.
Maybe I should write one on my own
-^-^-^-^-^-
no risk no funk
|
|
|
|
|
Can anyone tell me how to add header and footer to a dynamically generated word document using .net 2.0 ? I am able to generate the word document but i am unable to add/make visible the headers and footers in the document. I want page numbers to be coming up in the footers and some text in the ... I am using ASP.NET C#...
Nitin Kumar V , .NET Developer
|
|
|
|
|
I have been looking around and can not find what I am looking for. Thanks in advance for any help.
What I have is a very nice working form that does everything that I need, including handling WndProc messages. The problem is in converting this into a Windows Service.
I specifically designed it as a form for easier testing and because the documentation suggests that I will need a Form in my Windows service to handle WndProc events anyway.
Multiple inheritance would be fantastic, but doesn't exist for C#. I have tried multiple Interface inheritance but then I can not override the WndProc method.
If anyone knows how to add a form to a Windows Service to handle WndProc messages - or knows of any other way to enable WndProc overriding from within a Windows Service I would very much like to hear from you.
Regards,
Ben
|
|
|
|
|
Hi,
I have not done this before, but here is what I would try:
create an extra thread, and let it basically do what your current Main() method does,
i.e. creating a Form, and calling Application.Run()
Run() executes a message pump, which is one thing you need. There are some overloads for it,
the default one shows the form; you probably dont want that.
I trust a form, even if invisible, gets Windows messages, hence your overriden
WndProc could work as before.
There may be a problem the service not willing to create Controls (and Forms), lacking
a user. As I said, I never did it.
|
|
|
|
|
please help me
I want to insert new rows into the DataGrid for WindowsCE4.2 Application using c#2003
-- modified at 6:06 Sunday 22nd July, 2007
|
|
|
|
|
i developed windows service which generates crystal report and it is converted to pdf and also a mail was sent.
But my doubt is i want to generate this report evry day at 8:00pm...can anybody help me..give me the logic or any links
rajesh m
|
|
|
|
|
Hello,
I know there is a TabControl that allows you to click on tabs and each tab associated with a box, with different content.
Is there a way to do the same with TreeView? IE, what I need is a TabControl, but instead of showing tabs, it will be controlled by TreeView.
Hope I made myself clear...
- Eli Baskin.
|
|
|
|
|
It's possible but requires some more work.
You could for instance create a form with a tablelayoutpanel with two columns and 1 row.
In the left cell you add a treeview and you leave the righthand cell empty.
Then go to your solution and rightclick to 'Add->New Item', and select 'Custom Control'. Add one control for each of the "pages" you want to view for each of the nodes in the treeview.
Then add content to the various custom controls according to what you want on your "pages".
Create an instance of each of the custom controls in your forms constructor, and when you start adding the treeview nodes, you can add one of the custom control instances to each node.Tag property and a name for the "page" to the Text property of the node.
Finally in the treeviews node clicked event, you retrieve the node.Tag property, cast it to a usercontrol and add it to the tablelayoutpanel in the righthand cell.
-Larantz-
|
|
|
|
|
A bit too complicated for me, I am pretty novice in C#. My previous experiences were C, Delphi and LPC...
Do you know if there is a ready component that can do it?
|
|
|
|
|
hi
how can i change the currentrow in a datagridview.
some of rows in my datagrid is readonly and i want to jump to the next(or per) row to alow user to enter data.
the currentrow is readonly .
i used the currentcell but .....
please F1 me
thanX
|
|
|
|
|
I am working on ASP.NET. I would like to know how to highlight the row of records with colour in grid upon the page is loaded. My grid binds to a data source that run a stored procedure. The result of the stored procedure shows the current and previous records. Therefore, my user would like to know which row has been updated to the current value. Using the colour would identified the differences in the grid.
Please help.
Looking forward from your response.
Thank you.
Tyng
|
|
|
|
|
I have added some of the messages to my message queue yesterday but now i tried to iterate it now but no messages are there in the message queue can anybody tell me why and give me a suggestion to maintain all the messages in the message queue even though i restart my system.
Best Regards,
M. J. Jaya Chitra
|
|
|
|