循环中使用Asyncio调用Graph API遇Event loop is closed问题求助
问题原因分析
核心问题出在 msgraph-sdk异步客户端与事件循环的绑定关系:
asyncio.run()每次调用都会创建新的事件循环,执行完毕后会自动关闭该循环。- 当你第一次初始化GraphServiceClient时,客户端会绑定到当前的事件循环。第二次循环调用
asyncio.run()时,虽然新建了循环,但客户端仍然关联着已关闭的旧循环,调用API时就会触发"Event loop is closed"错误。 - 你之前尝试的三种方法没解决,大概率是因为没有处理客户端与循环的绑定问题——比如复用了同一个客户端实例,或者自定义循环时没有重新初始化客户端。
解决方案
提供两种可行思路,根据你的场景选择:
方案一:每次循环重新初始化Graph客户端
每次处理一组数据前,都创建新的GraphServiceClient实例,确保客户端绑定到当前循环:
import asyncio from msgraph import GraphServiceClient from azure.identity import ClientSecretCredential async def get_all_group_members(graph_client, group_ids): members = [] for group_id in group_ids: result = await graph_client.groups.by_group_id(group_id).members.get() members.extend(result.value) return members async def get_user_name(graph_client, user_ids): user_names = {} for user_id in user_ids: user = await graph_client.users.by_user_id(user_id).get() user_names[user_id] = user.display_name return user_names async def process_single_group(group_ids, user_ids): # 每次处理都重新初始化客户端,绑定当前循环 cred = ClientSecretCredential(tenant_id="你的租户ID", client_id="你的客户端ID", client_secret="你的客户端密钥") graph_client = GraphServiceClient(cred) members = await get_all_group_members(graph_client, group_ids) names = await get_user_name(graph_client, user_ids) return members, names def process_multiple_groups(groups_data): for group_data in groups_data: group_ids, user_ids = group_data result = asyncio.run(process_single_group(group_ids, user_ids)) print(result) # 测试数据 groups_data = [ (["group_id_1"], ["user_id_1"]), (["group_id_2"], ["user_id_2"]) ] process_multiple_groups(groups_data)
方案二:在单个事件循环内处理所有迭代
只初始化一次客户端,在同一个事件循环中批量处理所有数据,减少认证开销,效率更高:
import asyncio from msgraph import GraphServiceClient from azure.identity import ClientSecretCredential async def get_all_group_members(graph_client, group_ids): members = [] for group_id in group_ids: result = await graph_client.groups.by_group_id(group_id).members.get() members.extend(result.value) return members async def get_user_name(graph_client, user_ids): user_names = {} for user_id in user_ids: user = await graph_client.users.by_user_id(user_id).get() user_names[user_id] = user.display_name return user_names async def process_single_group(graph_client, group_ids, user_ids): members = await get_all_group_members(graph_client, group_ids) names = await get_user_name(graph_client, user_ids) return members, names async def process_all_groups(groups_data): # 仅初始化一次客户端,绑定到当前循环 cred = ClientSecretCredential(tenant_id="你的租户ID", client_id="你的客户端ID", client_secret="你的客户端密钥") graph_client = GraphServiceClient(cred) # 创建所有任务,可并发执行(如需顺序执行,改用逐个await) tasks = [process_single_group(graph_client, gid, uid) for gid, uid in groups_data] results = await asyncio.gather(*tasks) return results def main(): groups_data = [ (["group_id_1"], ["user_id_1"]), (["group_id_2"], ["user_id_2"]) ] results = asyncio.run(process_all_groups(groups_data)) for res in results: print(res) if __name__ == "__main__": main()
内容的提问来源于stack exchange,提问作者elahren
相关产品推荐
相关产品推荐

