I have a simple heartbeat method for my DB2/400:
public bool CheckConnection()
{
try
{
using (OleDbConnection db = new OleDbConnection( this.conString ))
{
OleDbCommand cmd = new OleDbCommand();
cmd.CommandText = "select 1 from sysibm.sysdummy1";
cmd.Connection = db;
db.Open();
cmd.ExecuteReader();
db.Close();
return true;
}
}
catch (Exception)
{
return false;
}
}
I want to use this when my application runs ,and of course i dont want to hold the execution of the rest of the form.
My main method in my form:
public FrmMain()
{
InitializeComponent();
PrepareFormTexts();
PrepareFormData();
PrepareStateClass();
CheckDbConnection();
//Initialize Data Access for AS400
Dal = JDE8Dal.Instance;
Dal.conString = Properties.Settings.Default.conAS400;
//Initialize Icons
picCon.Image = Properties.Resources.ledGreen;
picStatus.Image = Properties.Resources.ledGreen;
// Load recording from file if they exist
PrepareRecordings(AppState.DataFileName,'|');
}
CheckDbConnection method:
private async Task<bool> CheckDbConnection()
{
return await Task.Factory .StartNew(() => Dal.CheckConnection());
}
I think it runs fine but i get a warning
Warning 1 Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the ‘await’ operator to the result of the call.
Should i ignore it? should i put async in main method?
UPDATE: After discussing below i found out that since i am using async package for .NET 4.0 i cant really make my dal methods non-blocking. the only thing i can do is to use the async/await + task.factory.startnew in order to keep my app working while dal works on the background.
Code below:
public FrmMain()
{
InitializeComponent();
Load += FormLoadInit;
}
private async void FormLoadInit(object sender, EventArgs e)
{
PrepareFormTexts();
PrepareFormData();
PrepareStateClass();
txtLot.Select();
//Initialize Data Access for AS400
Dal = JDE8Dal.Instance;
Dal.conString = Properties.Settings.Default.conAS400;
// Load recording from file if they exist
PrepareRecordings(AppState.DataFileName, '|');
bool cn = await Task.Factory.StartNew(() => Dal.CheckConnection());
//Initialize Icons
picCon.Image = cn ? Resources.ledGreen : Resources.ledRed;
picStatus.Image = Properties.Resources.ledGreen;
}
What the warning is telling you is that you are effectively firing and then forgetting this asynchronous task. You never actually use the results of the operation, nor do you even store the
Taskitself to allow any future code to rely on it’s result (or even knowing when it finished).This won’t break anything, but it’s not really helpful either. You may as well just not call the method. Now, in your case this is just a dummy list, so you need to ask yourself what you’re trying to test. Do you want to display some dummy value on the form just as a proof of concept? If so, you’re code will need a few changes to get there.
To actually use the results of the query you’ll need to
awaitit, and you can’t do that from within a constructor. You’ll want to move the code to theForm Loadevent handler and mark the handler asasyncso that you canawaitwithin it.Another issue you have is that, to create your async method, you’re starting a new task that will run in a thread pool and then having it perform blocking methods. The primary advantage of using the async/await model is that you don’t need to do that. You should be using database querying methods that directly give you a
Task<T>as their return value and don’t block. You can thenawaiton those tasks (or just return them) such that your application has no threads being blocked while you wait.Your
CheckConnectionmethod should look something like this:CheckDbConnectionthen doesn’t need to exist. There’s no need to wrapCheckConnectionin aTaskbecause it already returns a task.