我需要一个方法,其中包括对数据库的调用。该方法必须与数据库的同步调用一起存在(将在SQL Server CLR中),并且与数据库的异步调用一起存在(将驻留在客户端应用程序中)。
在下面的示例中,我希望MyMethodSync和MyMethodAsync共享尽可能多的代码,理想情况下,我只希望使用1个带有布尔值“异步调用”的方法。
public static class MockDbAccess
{
public static int GetDbResult(int i, string sql = null)
{
return i + sql?.Length ?? 0;
}
async public static Task<int> GetDbResultAsync(int i, string sql = null)
{
await Task.Delay(2);
return i + sql?.Length ?? 0;
}
}
public class MyClass
{
const string SQL = "SELECT Value FROM Table1 WHERE UniqueCode = @I";
// COPY PASTE version:
public int MyMethodSync(int i)
{
var r1 = i + 4;
var r2 = MockDbAccess.GetDbResult(r1, SQL);
var r3 = r1 + r2 * 7;
return r3;
}
async public Task<int> MyMethodAsync(int i)
{
var r1 = i + 4;
var r2 = await MockDbAccess.GetDbResultAsync(r1, SQL);
var r3 = r1 + r2 * 7;
return r3;
}
// SHARED BUSINESS LOGIC attempt:
int GetR1(int i) => i + 4;
int GetR3(int r1, int r2) => r1 + r2 * 7;
public int MyMethodSync_SharedCode(int i)
{
var r1 = GetR1(i);
var r2 = MockDbAccess.GetDbResult(r1, SQL);
var r3 = GetR3(r1, r2);
return r3;
}
async public Task<int> MyMethodAsync_SharedCode(int i)
{
var r1 = GetR1(i);
var r2 = await MockDbAccess.GetDbResultAsync(r1, SQL);
var r3 = GetR3(r1, r2);
return r3;
}
}
据我所知,“共享业务逻辑”部分的尝试。显然,在我的应用程序中,get GetR1和GetR3方法要复杂得多。
编辑-进行澄清: 我需要同步版本来调用GetDbResult()方法(假设它是对SQL Server db的一些ADO.NET调用),并且需要异步以等待GetDbResultAsync()(这是对ASP.NET核心Web服务的调用)。结果是完全一样的,区别只是对DB的同步调用与异步调用。
答案 0 :(得分:1)
不幸的是,没有完美的解决方案。目前有两种中途的方法:
admin.firestore().collection('notifications').orderBy("date",'desc').limit(1)
,以便同步使用者可以阻止您返回的任务。布尔参数hack的工作原理是使用带有ConfigureAwait(false)
参数的核心方法,严格的语义是,如果该参数指示结果必须是同步的,则核心方法必须返回一个已经完成的任务。这样可以使调用代码安全地对其进行阻止:
bool
答案 1 :(得分:-1)
如果您要进行异步通话:
await MockDbAccess.GetDbResultAsync(r1, SQL);
如果您要同步通话:
MockDbAccess.GetDbResultAsync(r1, SQL).GetAwaiter().GetResult();
任何地方都可以结束此操作:
.ConfigureAwait(false);
答案 2 :(得分:-1)
理想情况下,我只想使用1个布尔型“异步调用”方法。
我认为这是可行的。在下面的示例中,可以安全地调用用Result
返回的任务的async: false
,因为Hybrid方法内部没有等待,因此该任务正在同步运行。
private async Task<int> MyMethodHybrid(int i, bool async)
{
var r1 = i + 4;
var r2 = async ?
await MockDbAccess.GetDbResultAsync(r1) :
MockDbAccess.GetDbResult(r1);
var r3 = r1 + r2 * 7;
return r3;
}
public int MyMethod(int i) => MyMethodHybrid(i, false).Result;
public Task<int> MyMethodAsync(int i) => MyMethodHybrid(i, true);
答案 3 :(得分:-3)
这两种方法将具有完全不同的返回类型(bool与Task
话虽如此,如果您实现了异步版本,那么同步版本只能调用异步版本:
public Task<bool> MyFuncAsync()
{
return true;
}
public bool MyFunc()
{
return MyFuncAsync().Result;
}