Using await/async Correctly
-
I'm a bit confused on something. I have a Sharepoint class with a DownloadFileAsync method:
using System.IO;
using System.Threading.Tasks;namespace WpfApp1
{
internal class Sharepoint
{
public async Task DownloadFileAsync(string folderName, string downloadPath = null)
{
var url = _clientContext.Web.ServerRelativeUrl + "/Shared%20Documents/" + folderName;
Folder targetFolder = _clientContext.Web.GetFolderByServerRelativeUrl(url);
_clientContext.Load(targetFolder.Files);await \_clientContext.ExecuteQueryAsync(); foreach (var file in targetFolder.Files) { FileInformation sharepointFile = Microsoft.SharePoint.Client.File.OpenBinaryDirect(\_clientContext, file.ServerRelativeUrl); await \_clientContext.ExecuteQueryAsync(); var path = string.IsNullOrEmpty(downloadPath) ? DEFAULT\_DIRECTORY : downloadPath; path = path + @"\\" + file.Name; using (FileStream filestream = new FileStream(path, FileMode.Create)) { sharepointFile.Stream.CopyTo(filestream); } } } }
}
It is called from a Repository class
using System.IO;
using System.Threading.Tasks;namespace WpfApp1
{
internal class Repository
{
string _appPath;
Sharepoint _sharePoint;public Repository() { \_sharePoint = new Sharepoint(); \_appPath = $"{Path.GetTempPath()}RDSPaymentProcessing"; } public async Task GETDataAsync() { var results = new MyData(); // If the local file already exists, delete it var fileName = $"{Path.GetTempPath()}{LOCAL\_APP\_DATA\_FOLDER}\\\\sharepointdata.xml"; if (File.Exists(fileName)) { File.Delete(fileName); } // Download all files from the Settings folder into the local user's app path await \_sharePoint.DownloadFile(SETINGS\_FOLDER, \_appPath); // If the file was downloaded... if (File.Exists(fileName)) { // Deserialize it results = Serialization.DeSerializeObject(fileName); } else { //TODO: Replace with custom exception throw new FileNotFoundException(fi
-
I'm a bit confused on something. I have a Sharepoint class with a DownloadFileAsync method:
using System.IO;
using System.Threading.Tasks;namespace WpfApp1
{
internal class Sharepoint
{
public async Task DownloadFileAsync(string folderName, string downloadPath = null)
{
var url = _clientContext.Web.ServerRelativeUrl + "/Shared%20Documents/" + folderName;
Folder targetFolder = _clientContext.Web.GetFolderByServerRelativeUrl(url);
_clientContext.Load(targetFolder.Files);await \_clientContext.ExecuteQueryAsync(); foreach (var file in targetFolder.Files) { FileInformation sharepointFile = Microsoft.SharePoint.Client.File.OpenBinaryDirect(\_clientContext, file.ServerRelativeUrl); await \_clientContext.ExecuteQueryAsync(); var path = string.IsNullOrEmpty(downloadPath) ? DEFAULT\_DIRECTORY : downloadPath; path = path + @"\\" + file.Name; using (FileStream filestream = new FileStream(path, FileMode.Create)) { sharepointFile.Stream.CopyTo(filestream); } } } }
}
It is called from a Repository class
using System.IO;
using System.Threading.Tasks;namespace WpfApp1
{
internal class Repository
{
string _appPath;
Sharepoint _sharePoint;public Repository() { \_sharePoint = new Sharepoint(); \_appPath = $"{Path.GetTempPath()}RDSPaymentProcessing"; } public async Task GETDataAsync() { var results = new MyData(); // If the local file already exists, delete it var fileName = $"{Path.GetTempPath()}{LOCAL\_APP\_DATA\_FOLDER}\\\\sharepointdata.xml"; if (File.Exists(fileName)) { File.Delete(fileName); } // Download all files from the Settings folder into the local user's app path await \_sharePoint.DownloadFile(SETINGS\_FOLDER, \_appPath); // If the file was downloaded... if (File.Exists(fileName)) { // Deserialize it results = Serialization.DeSerializeObject(fileName); } else { //TODO: Replace with custom exception throw new FileNotFoundException(fi
Use a BackgroundWorker; it's easier to get one's head around. About the only thing one is interested in with async is: 1) Is it finished (callback) 2) When can I use the data (use "concurrent" collections and events).
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
-
Use a BackgroundWorker; it's easier to get one's head around. About the only thing one is interested in with async is: 1) Is it finished (callback) 2) When can I use the data (use "concurrent" collections and events).
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
Hmm. I always thought background workers were 'outdated'. Seems to me that all you hear about these days is async/await.
In theory, theory and practice are the same. But in practice, they never are.” If it's not broken, fix it until it is. Everything makes sense in someone's mind.
-
Hmm. I always thought background workers were 'outdated'. Seems to me that all you hear about these days is async/await.
In theory, theory and practice are the same. But in practice, they never are.” If it's not broken, fix it until it is. Everything makes sense in someone's mind.
Wood working tools are also "outdated" by that logic.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
-
I'm a bit confused on something. I have a Sharepoint class with a DownloadFileAsync method:
using System.IO;
using System.Threading.Tasks;namespace WpfApp1
{
internal class Sharepoint
{
public async Task DownloadFileAsync(string folderName, string downloadPath = null)
{
var url = _clientContext.Web.ServerRelativeUrl + "/Shared%20Documents/" + folderName;
Folder targetFolder = _clientContext.Web.GetFolderByServerRelativeUrl(url);
_clientContext.Load(targetFolder.Files);await \_clientContext.ExecuteQueryAsync(); foreach (var file in targetFolder.Files) { FileInformation sharepointFile = Microsoft.SharePoint.Client.File.OpenBinaryDirect(\_clientContext, file.ServerRelativeUrl); await \_clientContext.ExecuteQueryAsync(); var path = string.IsNullOrEmpty(downloadPath) ? DEFAULT\_DIRECTORY : downloadPath; path = path + @"\\" + file.Name; using (FileStream filestream = new FileStream(path, FileMode.Create)) { sharepointFile.Stream.CopyTo(filestream); } } } }
}
It is called from a Repository class
using System.IO;
using System.Threading.Tasks;namespace WpfApp1
{
internal class Repository
{
string _appPath;
Sharepoint _sharePoint;public Repository() { \_sharePoint = new Sharepoint(); \_appPath = $"{Path.GetTempPath()}RDSPaymentProcessing"; } public async Task GETDataAsync() { var results = new MyData(); // If the local file already exists, delete it var fileName = $"{Path.GetTempPath()}{LOCAL\_APP\_DATA\_FOLDER}\\\\sharepointdata.xml"; if (File.Exists(fileName)) { File.Delete(fileName); } // Download all files from the Settings folder into the local user's app path await \_sharePoint.DownloadFile(SETINGS\_FOLDER, \_appPath); // If the file was downloaded... if (File.Exists(fileName)) { // Deserialize it results = Serialization.DeSerializeObject(fileName); } else { //TODO: Replace with custom exception throw new FileNotFoundException(fi
You should generally avoid
async void
methods[^]. As per David Fowler's async guidance[^], you can either useTask.Run
to push the execution onto a background thread, or call aTask
-returning method and "discard" the returned task. Either option will allow exceptions to fire theTaskScheduler.UnobservedTaskException
event[^] rather than crashing the application from the finalizer thread. In this case:internal class MainWindowViewModel
{
private MyEntity _data;private async Task LoadData() { \_data = await \_repository.GETDataAsync(); // TODO: Raise any "property changed" events to notify the view that the data has loaded. } public void WindowLoadedExecuted() { \_ = LoadData(); }
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer