Please if this question off-topic you can write in a comment to delete it later :)
If i have a 3 Layers ( *.DLL's )
In my application i make BusinessLogicLayer methods return Task and in UI Application i call await when i use a method from BusinessLogicLayer
I have misunderstanding the following:
My simple code contains the following :
DataAccessLayer.DLL a single method
public void MoveNext()
{
if (RecordCount == 0) return;
Tables[0].Query.Criteria.Clear();
Tables[0].Query.Sorting = $"ORDER BY {string.Join(" ASC, ",
Tables[0].Keys.Select(x => x.KeyID))} ASC";
FetchDataBuffer();
}
BusinessLogicLayer.DLL now wrapped the method of dataaccess in simple manner
public Task MoveNext() => Task.Run(() => { EntryBase.MoveNext(); });
UI Layer ( Any application or front-end provider in .NET )
private async void BtnNext_ItemClick(object sender, ClickEventArgs e)
{
await EntryLogic.MoveNext();
DeserializeBuffer();
}
As seen above the DeserializeBuffer method will not execute until the concurrency method ( MoveNext ) is finished.
What i need to make is get rid off await's keywords and async in UI layer.
What i actually do is failed and don't know why this happen
Scenario i try to make as following:
Convert the method type of DataAccessLayer from void to Task
public Task MoveNext()
{
return Task.Run(() => {
if (RecordCount == 0) return;
Tables[0].Query.Criteria.Clear();
Tables[0].Query.Sorting = $"ORDER BY {string.Join(" ASC, ",
Tables[0].Keys.Select(x => x.KeyID))} ASC";
FetchDataBuffer();
});
}
Then call await in Middle-were layer BusinessLogicLayer
public async void MoveNext() => await EntryBase.MoveNext();
After that calling the MoveNext in UI Layer from Logic layer. i guess that will make it awaitable because it already declared await in middle-were layer. but actually the UI layer executes the next method simultaneously. so the exceptions thrown because off next method ( DeserializeBuffer) depending on previous method ( EntryLogic.MoveNext)
private async void BtnNext_ItemClick(object sender, ClickEventArgs e)
{
EntryLogic.MoveNext();
DeserializeBuffer(); // exception thrown
/* because EntryLogic.MoveNext
is still executing and not awaited */
}
Any help would be appreciated.
What i need to make is get rid off await's keywords and async in UI layer.
This is exactly wrong. The UI layer is the only place where async
and await
must be used. And they do have to be used in that layer.
Your data access technology is unspecified, but from the code, I'm guessing it may be DataTable
-based, which is problematic because DataTable
is extremely old and does not support async
. Note that wrapping method bodies with Task.Run
to "make them asynchronous" is an antipattern - those are actually fake-asynchronous methods, not truly asynchronous.
If I'm wrong and your data-access technology does support async
, then you should be able to make your DAL methods async
without using Task.Run
. Start at the lowest level (e.g., whatever methods FetchDataBuffer
calls) and change them to the asynchronous equivalents. Then let async
grow from there. Note that "letting async grow" means using async Task
, not async void
; async void
in the BLL is definitely an antipattern.
But if I'm right and your DAL is using DataTable
, then you need to decide whether to switch to a newer data-access technology. If this isn't something you can do right now, then I'd recommend keeping the existing DAL and BLL code and just adding async
/await
to the UI layer:
private async void BtnNext_ItemClick(object sender, ClickEventArgs e)
{
await Task.Run(() => EntryLogic.MoveNext());
DeserializeBuffer();
}
This is not an antipattern because we're using Task.Run
to invoke a method - to move it off the UI thread. It's not ideal, since we're still using more threads than necessary, but an ideal solution would require true asynchronous data access. With this kind of compromise, your DAL and BLL are still blocking, so they have limited use outside of desktop UI applications.