亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何進行多個異步調用并從找到匹配記錄的第一次調用返回數據然后停止剩余的異步調用

如何進行多個異步調用并從找到匹配記錄的第一次調用返回數據然后停止剩余的異步調用

C#
翻翻過去那場雪 2023-05-14 16:14:08
我需要通過遍歷連接字符串來進行多個數據庫調用。數據庫中只有 1 條匹配記錄,如果我找到匹配記錄,那么我可以返回數據并取消其他異步調用。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 further process.(don't care about other calls if any single call finds data.                   context.Insurance.GetInsuranceByANI(ani);    }}通過 ANI 獲取保險public Task<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 Task.FromResult(MapInsurance(rdr));    }}例如:我正在循環使用 5(a, b, c, d, e) 個不同的數據庫連接字符串。我需要對所有 5 個數據庫進行異步調用。如果我在 db : b 中找到匹配的記錄,那么我可以返回該數據并繼續下一步,并且可以停止調用其他數據庫
查看完整描述

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();

                }

           }

    }


查看完整回答
反對 回復 2023-05-14
?
子衿沉夜

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

}


查看完整回答
反對 回復 2023-05-14
  • 2 回答
  • 0 關注
  • 170 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號