1

In my application I want to setup my ViewModels by queried data (from async methods) right after my application started.
In my case I have a .NET Framework WPF application and after the start I want to begin loading the data by async methods. After awaiting the data I want to update my view models.

What is the best way and the best entry point to do this?

My first approach is the following:

public App()
{
    // Do synchronous initializing stuff

    // Load data and initialize by viewmodel with it
#pragma warning disable CS4014
    ProgramStateViewModel.Instance.LoadDataAndSetupAsync();
#pragma warning restore CS4014
}

The problem with this is I got the compiler warning and I have to handle it by suppressing it. Actually I want a Fire-and-Forget call, but the method I am calling is async and returns a Task. How to do it better?

rittergig
  • 715
  • 1
  • 5
  • 16

3 Answers3

3

You can attach an async Startup event handler:

public App()
{
    Startup += async (s, e) =>
    {
        await ProgramStateViewModel.Instance.LoadDataAndSetupAsync();
    };
}
Clemens
  • 123,504
  • 12
  • 155
  • 268
0

Try the following, using discards:

public App()
{
    // Do synchronous initializing stuff

    // Load data and initialize by viewmodel with it
    _ = ProgramStateViewModel.Instance.LoadDataAndSetupAsync();
}

By using discards, you can return the Task and you don't declare anything else that will not be used.

Be aware that even without the warning the dangers still apply.

Especially if you have an error in your background work which well not be caught. To avoid this situation, please check another SO question here on managing exceptions on the separate thread.

Athanasios Kataras
  • 25,191
  • 4
  • 32
  • 61
-1

A possibility is to use the OnStartup function in the App.xaml.cs file. For the asynchronous call, various methods exist, following some methods to make an asynchronous call.

Using BackgroundWorker

public partial class App : Application
{
  protected override void OnStartup(System.Windows.StartupEventArgs e)
  { 
    BackgroundWorker _backgroundWorker;
    if (_backgroundWorker != null)
    {
     _backgroundWorker.CancelAsync();
    }
    _backgroundWorker = CreateBackgroundWorker();
    _backgroundWorker.RunWorkerAsync(); 
  }
}

private BackgroundWorker CreateBackgroundWorker()
{
    var bw = new BackgroundWorker();
    bw.WorkerReportsProgress = true;
    bw.WorkerSupportsCancellation = true;
    bw.DoWork += _backgroundWorker_DoWork;
    bw.ProgressChanged += _backgroundWorker_ProgressChanged;
    bw.RunWorkerCompleted +=  _backgroundWorker_RunWorkerCompleted;
    return bw;
}

private void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
}

private void _backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{

}

private void _backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{

}

Using Thread

Method 1

myThread = new Thread(() => CustomTaskAsync());
myThread.Start();

private void CustomTaskAsync()
{
    ...............
}

Method 2

Thread thread = new Thread(new ThreadStart(CustomTaskAsync));
thread.Start();

public void CustomTaskAsync()
{
   ..................
}

Method 3

Thread thread = new Thread(CustomTaskAsync);
thread.Start();

public void CustomTaskAsync()
{
  ...............
}

Using Task

Method 1

bool result ;
Task<bool> task = Task.Run<bool>(async () => await CustomTaskAsync());
str = task.Result;

public async Task<bool> CustomTaskAsync()
{
   bool result;
   result= await Task.Factory.StartNew(() => CustomTask());
   return result;
}

private bool CustomTask()
{           
  bool result;  
 return result;
}

Method 2

CustomTaskAsync().Wait();  

public async Task CustomTaskAsync()
{
   await Task.Run(() => {
    .................
   });
}
LPGTE SOFTS
  • 120
  • 8