C
C#2mo ago
hickensa

why is this only occasionally async

private void button12_Click(object sender, EventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += Worker_DoVSC;
worker.RunWorkerAsync();
}

private void Worker_DoVSC(object sender, DoWorkEventArgs e)
{
Download_VSC();
}
private void Download_VSC()
{
this.BeginInvoke(new Action(() =>
{
label2.Text = "Downloading Visual Studio Code..."; label2.Refresh();
this.Hide();
dl = new WebClient();
dl.DownloadFileCompleted += dl_DownloadFileCompleted;
dl.DownloadProgressChanged += dl_DownloadProgressChanged;
this.Show();
dl.DownloadFileAsync(new Uri("https://code.visualstudio.com/sha/download?build=stable&os=win32-x64-user"), "C:\\Downloads\\VSCodeUserSetup.exe");
sw.Start();
}));
}
private void button12_Click(object sender, EventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += Worker_DoVSC;
worker.RunWorkerAsync();
}

private void Worker_DoVSC(object sender, DoWorkEventArgs e)
{
Download_VSC();
}
private void Download_VSC()
{
this.BeginInvoke(new Action(() =>
{
label2.Text = "Downloading Visual Studio Code..."; label2.Refresh();
this.Hide();
dl = new WebClient();
dl.DownloadFileCompleted += dl_DownloadFileCompleted;
dl.DownloadProgressChanged += dl_DownloadProgressChanged;
this.Show();
dl.DownloadFileAsync(new Uri("https://code.visualstudio.com/sha/download?build=stable&os=win32-x64-user"), "C:\\Downloads\\VSCodeUserSetup.exe");
sw.Start();
}));
}
the main reason for why I need this to be async is because it is an entire form with downloads that has a progress bar a total size and live updating download speed and current mb downloaded (the reason why there is a stopwatch) I have managed to get it to be this exact code here and async a few times although most of the time it isn't
47 Replies
Angius
Angius2mo ago
You say you need it to be async, but nothing in your code is async Well, there's one method with Async suffix in the name But it's not handled like an asynchronous method should be
SG97
SG972mo ago
"We don't recommend that you use the WebClient class for new development. Instead, use the System.Net.Http.HttpClient class." https://learn.microsoft.com/en-us/dotnet/api/system.net.webclient?view=net-8.0
hickensa
hickensa2mo ago
I personally prefer webclient I mean other downloads are async and the format is the same just changed link and filename They are smaller files though The worker itself is being ran asynchronously Adding the suffixes async did not do anything
Angius
Angius2mo ago
You can't say "I need this to be async" and "I prefer Webclient" at the same time Webclient is not, never was, and never will be async The Async suffixed method is not asynchronous either
hickensa
hickensa2mo ago
I've seen webclient being async before
Angius
Angius2mo ago
It's not Never was
hickensa
hickensa2mo ago
The workaround is refreshing the form Worked pretty well for one of my friends Not too much for me
Angius
Angius2mo ago
Never will be
hickensa
hickensa2mo ago
I mean I can record my code being async if I can get it to async again still using webclient Or record a more consistently async download Again still using webclient
Angius
Angius2mo ago
Again None of your code is asynchronous None of it Zero percent .BeginInvoke() kinda sorta tries to look like it's async I guess
hickensa
hickensa2mo ago
explain this:
hickensa
hickensa2mo ago
forgot to show it downloaded oh well
Angius
Angius2mo ago
I guess we have a different definition, then. To me, async is... well, async and await But Winforms seems to have its own weird magic
hickensa
hickensa2mo ago
yeah I only ever need the ui to be updatable so the speed and progress can change
Angius
Angius2mo ago
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.control.begininvoke?view=windowsdesktop-8.0
Executes a delegate asynchronously on the thread that the control's underlying handle was created on.
Could it be that the thread is the main UI thread? That would cause it to block the main thread
hickensa
hickensa2mo ago
probably
reflectronic
reflectronic2mo ago
you have made this code remarkably complicated by not using HttpClient well. i guess it is harder to get the progress with HttpClient. fine, whatever but, do not use BackgroundWorker the BackgroundWorker is completely pointless here, the first thing you do in the BackgroundWorker is go back to the UI thread to do everything you could have just put the stuff inside BeginInvoke right into button_Click and the effect would be the same
hickensa
hickensa2mo ago
did try that before still not async
reflectronic
reflectronic2mo ago
i mean. it is a fact that the BackgroundWorker does nothing here. you are not doing anything in the background, it does not make anything asynchronous. so there's no point in having it as for why it's only "occasionally async," you would need to show what you mean exactly
hickensa
hickensa2mo ago
so I have managed to have it async a few times it is async sometimes although rarely
reflectronic
reflectronic2mo ago
i don't understand what it means for it to be not async
hickensa
hickensa2mo ago
ui not updating in this case
hickensa
hickensa2mo ago
this also shows how it sometimes is async and sometimes isnt I dont even understand how that part works
leowest
leowest2mo ago
why are u using a backgroundworker and not even using the backgroundWorker_ProgressChanged of it which would be the correct way to update your GUI without locking it up by overloading the invoker?
reflectronic
reflectronic2mo ago
ok. well, to be clear, it is asynchronous. you can tell because the progress bar is updating. if it was not asynchronous, it would not move at all it is hard to say what the problem is without seeing dl_DownloadProgressChanged
hickensa
hickensa2mo ago
private void dl_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) { this.BeginInvoke(new Action(() => { lblSpeed.Text = string.Format("{0} kb/s", (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds).ToString("0.00")); lblDownload.Text = string.Format("{0} MB / {1} MB", (e.BytesReceived / 1024d / 1024d).ToString("0.00"), (e.TotalBytesToReceive / 1024d / 1024d).ToString("0.00")); progressBar1.Value = e.ProgressPercentage; })); }
leowest
leowest2mo ago
u dont need invoke in the progresschanged progresschanged happens in the ui thread
hickensa
hickensa2mo ago
I did try doing it without it before and that caused issues one time and reverted it based on the fact this ui is generally inconsistent I am surprised I didnt have that happen even with it
leowest
leowest2mo ago
like what specifically?
hickensa
hickensa2mo ago
the progress bar just didnt do anything
leowest
leowest2mo ago
I doubt that was the cause giving you're invoking everywhere
hickensa
hickensa2mo ago
I'll try again to remove it
hickensa
hickensa2mo ago
and another problem the progress bar doesnt reset
No description
leowest
leowest2mo ago
BlazeBin - llviodhkmebw
A tool for sharing your source code with the world!
leowest
leowest2mo ago
its not my code, I think I found it on stackoverflow long time ago, but its much better than using webclient
hickensa
hickensa2mo ago
BlazeBin - urevhknroxjy
A tool for sharing your source code with the world!
hickensa
hickensa2mo ago
I forgot to vopy the main download page I just added utils fixed it it's a mess needed to remove advertising
leowest
leowest2mo ago
ah ok because that progresschanged is not the backgroundworker one that's why it doesnt work
reflectronic
reflectronic2mo ago
it's hard to say what's wrong because the given code looks completely fine like, the progress bar is clearly updating, it's unclear why updating the labels would not also work
hickensa
hickensa2mo ago
I should mention it only applies to larger files
leowest
leowest2mo ago
which is the largest file in your list
hickensa
hickensa2mo ago
edge webview installer 170mb
reflectronic
reflectronic2mo ago
does it help to get rid of the BeginInvoke in dl_DownloadProgressChanged and dl_DownloadFileCompleted
hickensa
hickensa2mo ago
nvm epic games launcher 177 no the progress bar still worked but didn't reset
reflectronic
reflectronic2mo ago
if you put a MessageBox.Show inside of DownloadFileCompleted, does the message box show up, even in the times when the progress bar does not reset
hickensa
hickensa2mo ago
sort of
No description
hickensa
hickensa2mo ago
and its memory leaking well not memory leaking in the full sense it's stacking the form over and over in memory