2 回答
TA贡献1864条经验 获得超6个赞
获取值后立即返回该值如何。不允许流程向前移动并打破循环。
using (var Contexts = instContextfactory.GetContextList())
{
foreach(var context in Contexts.GetContextList())
{
// how do I make all the calls and return data from the first call that finds data and continue with the further process.(don't care about other calls if any single call finds data.
var result = await context.Insurance.GetInsuranceByANI(ani);
if(result.Any())
{
return result.First();
}
}
}
TA贡献1828条经验 获得超3个赞
为了简单起见,您应该首先改回您的GetInsuranceByANI方法以再次同步。稍后我们将生成任务以异步调用它。
public IEnumerable<Insurance> GetInsuranceByANI(string ani)
{
using (ITransaction transaction = Session.Value.BeginTransaction())
{
transaction.Rollback();
IDbCommand command = new SqlCommand();
command.Connection = Session.Value.Connection;
transaction.Enlist(command);
string storedProcName = "spGetInsurance";
command.CommandText = storedProcName;
command.Parameters.Add(new SqlParameter("@ANI", SqlDbType.Char, 0, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Default, ani));
var rdr = command.ExecuteReader();
return MapInsurance(rdr);
}
}
现在来实现异步搜索所有数据库的方法。我们将为每个数据库创建一个任务,在线程池线程中运行。这是值得商榷的,但我们正在努力让事情变得简单。我们还实例化 a CancellationTokenSource,并将其传递Token给所有Task.Run方法。这只会确保在我们得到结果后,不会再启动更多任务。如果线程池中的可用线程多于要搜索的数据库,则所有任务将立即开始,取消令牌实际上不会取消任何内容。换句话说,无论如何,所有启动的查询都将完成。这显然是一种资源浪费,但我们再次努力让事情变得简单。
启动任务后,我们将进入一个等待下一个任务完成的循环(使用方法Task.WhenAny)。如果找到结果,我们取消令牌并返回结果。如果未找到结果,我们将继续循环以获得下一个结果。如果所有任务都完成但我们仍然没有结果,我们将返回 null。
async Task<IEnumerable<Insurance>> SearchAllByANI(string ani)
{
var tasks = new HashSet<Task<IEnumerable<Insurance>>>();
var cts = new CancellationTokenSource();
using (var Contexts = instContextfactory.GetContextList())
{
foreach (var context in Contexts.GetContextList())
{
tasks.Add(Task.Run(() =>
{
return context.Insurance.GetInsuranceByANI(ani);
}, cts.Token));
}
}
while (tasks.Count > 0)
{
var task = await Task.WhenAny(tasks);
var result = await task;
if (result != null && result.Any())
{
cts.Cancel();
return result;
}
tasks.Remove(task);
}
return null;
}
使用示例:
IEnumerable<Insurance> result = await SearchAllByANI("12345");
if (result == null)
{
// Nothing fould
}
else
{
// Do something with result
}
- 2 回答
- 0 关注
- 130 浏览
添加回答
举报