I have in my Form constructor, after the InitializeComponent the following code:
using (WebClient client = new WebClient())
{
client.DownloadDataCompleted += new DownloadDataCompletedEventHandler(client_DownloadDataCompleted);
client.DownloadDataAsync("http://example.com/version.txt");
}
When I start my form, the UI doesn't appears till client_DownloadDataCompleted is raised. The client_DownloadDataCompleted method is empty, so there's no problem there.
What I'm doing wrong? How is supposed to do this without freezing the UI?
Thanks for your time.
Best regards.
FULL CODE:
Program.cs
using System;
using System.Windows.Forms;
namespace Lala
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
Form1.cs
using System;
using System.Net;
using System.Windows.Forms;
namespace Lala
{
public partial class Form1 : Form
{
WebClient client = new WebClient();
public Form1()
{
client.DownloadDataCompleted += new DownloadDataCompletedEventHandler(client_DownloadDataCompleted);
client.DownloadDataAsync(new Uri("http://www.google.com"));
InitializeComponent();
}
void client_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
textBox1.Text += "A";
}
}
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(12, 12);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(12, 41);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(468, 213);
this.textBox1.TabIndex = 1;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(492, 266);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button button1;
private System.Windows.Forms.TextBox textBox1;
}
}
I've tried your code and it works fine.
Could you post your Main(Args[]) method and the value of a and b when this is run:
I tried it in .NET 3.5 and VS2008. I'm at a loss, but I am convinced it's to do with the setup on your machine. Not the code. Check these things:
I strongly suspect that it's to do with disposing of the WebClient while you're still using it for an asynchronous call.
Try removing the using statement, and call Dispose in an event handler instead. (Or just for testing, don't worry about disposing it at all.
If you could post a short but complete program which demonstrates the issue, that would be really handy.
You want to run the download in a different thread, see this as a starting point.
try this:
I've just tested the same thing in a WPF project under VS2010, .NET 4.
I'm downloading a file with a progress bar to show percentage completed using WebClient.DownloadDataCompleted etc.
And, to my amazement, I'm finding the same thing @Dan mentioned: Within the debugger it blocks the thread in a funny way. In debug, my progress meter gets updated at 1%, then does nothing for a while, then updates again suddenly at 100%. (Debug.WriteLn statements print smoothly throughout). And between these two times, the UI is frozen.
But outside the debugger, the progress bar moves smoothly from 0% to 100%, and the UI never freezes. Which is what you'd expect.
UNDELETED: As many think about the using block like I do, I've confirmed that it is not related.
Can you remove the using block, I think it is waiting to dispose the webclient instance.