WebClient does not support concurrent I/O operations - c#

I did what #Enigmativity write
here it is:
Action<int, ProgressBar, Label, Label, int, Button> downloadFileAsync = (i, pb, label2, label1, ServID, button1) =>
{
var bd = AppDomain.CurrentDomain.BaseDirectory;
var fn = bd + "/" + i + ".7z";
var down = new WebClient();
DownloadProgressChangedEventHandler dpc = (s, e) =>
{
label1.Text = "Download Update: " + i + " From: " + ServID;
int rec =Convert.ToInt16(e.BytesReceived / 1024);
int total =Convert.ToInt16(e.TotalBytesToReceive / 1024) ;
label2.Text = "Downloaded: " + rec.ToString() + " / " + total.ToString() + " KB";
pb.Value = e.ProgressPercentage;
};
AsyncCompletedEventHandler dfc = null; dfc = (s, e) =>
{
down.DownloadProgressChanged -= dpc;
down.DownloadFileCompleted -= dfc;
CompressionEngine.Current.Decoder.DecodeIntoDirectory(AppDomain.CurrentDomain.BaseDirectory + "/" + i + ".7z", AppDomain.CurrentDomain.BaseDirectory);
File.Delete(fn);
if (i == ServID)
{
button1.Enabled = true;
label1.Text = "Game Is Up-To-Date.Have Fun!!";
label2.Text = "Done..";
}
down.Dispose();
};
My only problam now is when the program is extarting the downloaded file
CompressionEngine.Current.Decoder.DecodeIntoDirectory(AppDomain.CurrentDomain.BaseDirectory + "/" + i + ".7z", AppDomain.CurrentDomain.BaseDirectory);
In some files its take time to extarct the downloaded file
so how i can tell the program to wait until decompressing is complete?

Try defining a single lambda that will encapsulate a single async download and then call that in a loop.
Here's the lambda:
Action<int> downloadFileAsync = i =>
{
var bd = AppDomain.CurrentDomain.BaseDirectory;
var fn = bd + "/" + i + ".7z";
var wc = new WebClient();
DownloadProgressChangedEventHandler dpc = (s, e) =>
{
progressBar1.Value = e.ProgressPercentage;
};
AsyncCompletedEventHandler dfc = null;
dfc = (s, e) =>
{
wc.DownloadProgressChanged -= dpc;
wc.DownloadFileCompleted -= dfc;
CompressionEngine.Current.Decoder.DecodeIntoDirectory(fn, bd);
File.Delete(fn);
wc.Dispose();
};
wc.DownloadProgressChanged += dpc;
wc.DownloadFileCompleted += dfc;
wc.DownloadFileAsync(new Uri(Dlpath + i + "/" + i + ".7z"), fn);
};
You'll note that it nicely detaches all events and also correctly disposes of the WebClient instance.
Now call it like this:
while (i <= ServID)
{
downloadFileAsync(i);
i++;
}
You'll have to fiddle with the progress bar update to properly show the progress of all the files downloading, but in principle this should work for you.

Related

I have a Qr generator application written in C#. So now i want to generate Qr Code that willl change in every 10 seconds during runtime

i want to generate the dynamic Qr code so please help me out how can i build a dynamic Qr code generator that will change during the run time in every 10 seconds
private void btnGenerate_Click(object sender, EventArgs e)
{
QRCoder.QRCodeGenerator QRGenerator = new QRCoder.QRCodeGenerator();
DateTime now = DateTime.Now;
dateTimePickerDate.Text = now.ToLongDateString();
txtTime.Text = now.ToShortTimeString();
var qrText = cmbSubject.Text + "\n" + txtSection.Text + "\n" + dateTimePickerDate.Text + "\n" + txtTime.Text + "\n";
var MyData = QRGenerator.CreateQrCode(cmbSubject.Text + ",\n" + txtSection.Text + ", \n" + dateTimePickerDate.Text + ",\n" + txtTime.Text + ",\n" + txtIP.Text + ",\n", QRCoder.QRCodeGenerator.ECCLevel.H);
var code = new QRCoder.QRCode(MyData);
pcQRImage.Image = code.GetGraphic(50);
}
You need to add a Timerto your Forms project e.g:
private Timer timerInterval = new Timer();
private QRCoder.QRCodeGenerator QRGenerator = new QRCoder.QRCodeGenerator();
private void btnGenerate_Click(object sender, EventArgs e)
{
timerInterval.Enabled = true;
timerInterval.Tick += timerInterval_Tick;
timerInterval.Interval = 10000;
timerInterval.Start();
}
private void timerInterval_Tick(object sender, EventArgs e)
{
DateTime now = DateTime.Now;
dateTimePickerDate.Text = now.ToLongDateString();
txtTime.Text = now.ToShortTimeString();
var qrText = cmbSubject.Text + "\n" + txtSection.Text + "\n" + dateTimePickerDate.Text + "\n" + txtTime.Text + "\n";
var MyData = QRGenerator.CreateQrCode(cmbSubject.Text + ",\n" + txtSection.Text + ", \n" + dateTimePickerDate.Text + ",\n" + txtTime.Text + ",\n" + txtIP.Text + ",\n", QRCoder.QRCodeGenerator.ECCLevel.H);
var code = new QRCoder.QRCode(MyData);
pcQRImage.Image = code.GetGraphic(50);
}
It is also possible to use System.Threading.Timer but then it will be necessary to Invoke your Form elements.
Hi you can try this method, this will instantiates the timer to fire every millisecond interval you set.
private void Form1_Load(object sender, EventArgs e)
{
System.Timers.Timer timerInterval = new System.Timers.Timer();
timerInterval.Elapsed += new ElapsedEventHandler(OnTimedEvent);
timerInterval.Interval = 10000;
timerInterval.Enabled = true;
}
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
QRCoder.QRCodeGenerator QRGenerator = new QRCoder.QRCodeGenerator();
DateTime now = DateTime.Now;
dateTimePickerDate.Text = now.ToLongDateString();
txtTime.Text = now.ToShortTimeString();
var qrText = cmbSubject.Text + "\n" + txtSection.Text + "\n" + dateTimePickerDate.Text + "\n" + txtTime.Text + "\n";
var MyData = QRGenerator.CreateQrCode(cmbSubject.Text + ",\n" + txtSection.Text + ", \n" + dateTimePickerDate.Text + ",\n" + txtTime.Text + ",\n" + txtIP.Text + ",\n", QRCoder.QRCodeGenerator.ECCLevel.H);
var code = new QRCoder.QRCode(MyData);
if(pcQRImage!=null)
{
pcQRImage.Dispose();
pcQRImage.Image = code.GetGraphic(50);
}
else
{
pcQRImage.Image = code.GetGraphic(50);
}
}

Download multiple files in C# (one at a time only / queue)

I'm writing an updater in C# and I need some help now (I'm new to this language, please explain your tips :D )
My Code:
System.IO.Directory.CreateDirectory("tmp");
int mmx = updnec.Count();
label6.Text = "0/" + mmx;
MessageBox.Show(label6.Text);
int mmn = 0;
foreach (string lz in link)
{
MessageBox.Show(lz);
client.DownloadFileAsync(new Uri(lz), "tmp/update00" + mmn + ".exe");
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
label6.Text = mmn + "/" + mmx;
mmn = +1;
//Whithout that while{} - part, it tries to download all links from the list at once. But I don't want the program to do that. I don't want it to show a message all the time, too, but when i leave that while{} - part empty, the program just freezes and doesn't even download.
while (progressBar1.Maximum != progressBar1.Value)
{
MessageBox.Show("Test");
}
}
}
void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
progressBar1.Maximum = (int)e.TotalBytesToReceive;
progressBar1.Value = (int)e.BytesReceived;
string sysload = progressBar1.Value /1000000 + "/" + progressBar1.Maximum /1000000 + " MB geladen";
label12.Text = sysload;
}
Read the comment int my code please.
How to solve my problem!? Please help me!
Reditec
Edit:
label11.Text = System.DateTime.Now.ToString();
backgroundWorker1.RunWorkerAsync(link);
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
List<string> lz = (List<string>)e.Argument;
int mmn = 0;
progressBar1.Style = ProgressBarStyle.Blocks;
System.IO.Directory.CreateDirectory("tmp");
int mmx = 10;
label6.Text = "0/" + mmx;
foreach (string lkz in lz)
using (var client = new WebClient())
{
MessageBox.Show("Hallo" + lkz);
client.DownloadFile(lkz, "tmp/update00" + mmn + ".exe");
}
}
Try use a BackgroundWorker and download your files in sync instead of async.
You can find an example here:
http://www.codeproject.com/Tips/83317/BackgroundWorker-and-ProgressBar-demo
Here is an example:
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var links = new[] { "link1", "link2" };
var percentProgressStep = (100 / links.Length) + 1
using (var client = new WebClient())
foreach (string l in links)
{
client.DownloadFile(l, Path.GetTempFileName());
backgroundWorker1.ReportProgress(percentProgressStep);
}
}

Zip the folder is not working first time C# and DotNetZip

I have a DotNetZip code for zipping the folder. It doesnt zip the file for the first time after cleaning the solution. After that it works fine. Can anybody know the issue why its happening??
Button Click Event Code
private void button3_Click(object sender, EventArgs e)
{
try
{
copy_stuff(textBox1.Text, textBox2.Text, textBox3.Text);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Method that gets called from Button Click
private void copy_stuff(string srcFolder, string destFolder, string Backup)
{
using (ZipFile zip = new ZipFile())
{
zip.AddProgress += AddProgressHandler;
zip.CompressionLevel = Ionic.Zlib.CompressionLevel.Default;
zip.SaveProgress += SaveProgress;
zip.StatusMessageTextWriter = System.Console.Out;
zip.AddDirectory(destFolder);
zip.Save(Backup + "\\VibrantBackup" + DateTime.Now.ToString("yyyyMMdd hh.mm.ss") + ".zip");
label1.Text = "Compression completed.";
}
}
Add & Save Handlers for Progress
int _numEntriesToAdd = 0;
int _numEntriesAdded = 0;
void AddProgressHandler(object sender, AddProgressEventArgs e)
{
switch (e.EventType)
{
case ZipProgressEventType.Adding_Started:
_numEntriesToAdd = 0;
_numEntriesAdded = 0;
label1.Text = "Adding files to the zip...";
label1.Update();
Application.DoEvents();
break;
case ZipProgressEventType.Adding_AfterAddEntry:
_numEntriesAdded++;
label1.Text = String.Format("Adding file: {0} :: {2}",
_numEntriesAdded, _numEntriesToAdd, e.CurrentEntry.FileName);
label1.Update();
Application.DoEvents();
break;
case ZipProgressEventType.Adding_Completed:
label1.Text = "Added all files";
label1.Update();
Application.DoEvents();
break;
}
}
public void SaveProgress(object sender, SaveProgressEventArgs e)
{
if (e.EventType == ZipProgressEventType.Saving_Started)
{
label1.Text = "Begin Saving: " + e.ArchiveName;
label1.Update();
Application.DoEvents();
}
else if (e.EventType == ZipProgressEventType.Saving_BeforeWriteEntry)
{
label1.Text = "Processing : " + e.CurrentEntry.FileName;
label1.Update();
label3.Text = "Files Processed: (" + (e.EntriesSaved + 1) + "/" + e.EntriesTotal + ")";
label3.Update();
Application.DoEvents();
progressBar3.Maximum = e.EntriesTotal;
progressBar3.Value = e.EntriesSaved + 1;
}
else if (e.EventType == ZipProgressEventType.Saving_EntryBytesRead)
{
//progressBar2.Value = (int)((e.BytesTransferred * 100) / e.TotalBytesToTransfer);
//label3.Text = "Writing: " + e.CurrentEntry.FileName + " (" + (e.EntriesSaved + 1) + "/" + e.EntriesTotal + ")";
label1.Update();
Application.DoEvents();
}
}

FTP download backgroundworker

I have this code but it's not working...
The progressbar is not moving and the downloaded file size is 0kb.
I think I have some problem in my WHILE loop! How can I solve this problem? Please give me instructions!
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
DirectoryInfo folder= new DirectoryInfo(#"C:\Cloud24");
try
{
{
long size= 0;
WebClient request = new WebClient();
request.Credentials = new NetworkCredential(userid, userpass);
FileStream file = File.Create(folder+ "//" + downloadname);
byte[] filedata = request.DownloadData(ftpadress + "/" + downloadname);
while ((size= file.Read(filedata, 0, filedata.Length)) > 0)
{
file.Write(filedata, 0, filedata.Length);
size += (int)filedata.Length;
double dProgressPercentage = ((double)(size) / (double)filedata.Length);
backgroundWorker1.ReportProgress((int)(dProgressPercentage * 100));
}
file.Close();
MessageBox.Show(downloadname + " downloaded!" +
Environment.NewLine + "There: " + folder);
}
}
catch (Exception exc)
{
MessageBox.Show("Error: " + exc.Message);
}
}
This should probably work, but I haven't actually tested it.
private async void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var folder = new DirectoryInfo(#"C:\Cloud24");
try
{
{
var manualResetEvent = new ManualResetEventSlim();
var client = new WebClient { Credentials = new NetworkCredential(userid, userpass) };
client.DownloadProgressChanged += (o, args) => backgroundWorker1.ReportProgress(args.ProgressPercentage);
client.DownloadDataCompleted += (o, args) => manualResetEvent.Set();
var filedata = client.DownloadDataAsync(ftpadress + "/" + downloadname);
manualResetEvent.Wait();
using (var stream = File.Create(folder + "//" + downloadname))
{
await stream.WriteAsync(filedata, 0, filedata.Length);
}
MessageBox.Show(downloadname + " downloaded!" + Environment.NewLine + "There: " + folder);
}
}
catch (Exception exc)
{
MessageBox.Show("Error: " + exc.Message);
}
}

UploadProgressChanged with Foreach

Ok, I have this:
foreach (FileInfo fileinfo2 in Arquivos2)
{
label8.Text = "Enviando(NFe): " + fileinfo2.Name + "...";
label8.Update();
WebClient client = new WebClient();
client.Credentials = new System.Net.NetworkCredential(usuario, senha);
client.UploadProgressChanged += new UploadProgressChangedEventHandler(UploadProgressCallback);
client.UploadFile(new Uri("ftp://" + ftp + "/" + caminho + "//nf//" + fileinfo2.Name), "STOR", #"C:\\NFe\" + fileinfo2.Name);
bar++;
backgroundWorker1.ReportProgress(bar);
}
Its work fine, but I have:
private void UploadProgressCallback(object sender, UploadProgressChangedEventArgs e)
{
progressBar2.Value = e.ProgressPercentage;
progressBar2.Update();
}
and nothing happens with progressBar2...
How I can update my progressBar2 with a uploadprogress? I can't use UploadFile with UploadProgressChanged?
According to http://msdn.microsoft.com/en-us/library/system.net.webclient.uploadprogresschanged.aspx
This event is raised each time an asynchronous upload makes progress.
It is only raised by 3 asynchronous events. The version you are calling is a blocking method and does not return until it completes and does not raise progress events.

Categories

Resources