当前位置: 首页 > 知识库问答 >
问题:

如何在C#中设计并行web api?

越勇锐
2023-03-14

我正在尝试设计一个可以从外部服务器获取数据但有限制的web api。我想知道如何最好的设计它是有效率的。

我的api有一个接受输入的endpoint。它是一个类似于tom@domain.com的域名。然后,我的endpoint对域进行http调用以获得一个身份验证令牌,然后使用用户名对该域进行另一次调用以获得一些返回给客户端的数据。但是,我的api可以接受多个用户名(逗号分隔,如?users=tom@domain.a.com,bill@domain.b.com)。我的web服务器知道每个域的最大并行连接数是多少以获取数据。

所以问题是如何组织数据,使我可以最大化并行计算,但保持在极限之内。

以下是我的想法:

首先解析用户列表并将其分组。然后有一个静态字典。键是域,值是有2个队列的自定义对象。这两个队列都包含任务列表(来自Async/Await)。但是,第一个队列最大长度将是该域的限制值。

?users=bill@D.com, max@D.com, sarah@A.com, tom@D.com

dictionary = {
    "D.com" : [
         [],
         ["bill@D.com", "max@D.com", "tom@D.com"]
     ],
     "A.com" : [
         [],
         ["sarah@A.com"]
     ]
}

然后,我可以每秒运行一段代码,循环所有字典值,用第二个队列中的任务对象填充第一个队列(例如,从第二个队列中移除并放入第一个),使其在限制范围内。

任务一旦进入第一个队列,就会使用parallel.invoke()执行,然后当任务完成时,它就会从第一个队列中删除(除非某个请求正在等待它,下一段将对此进行解释)。

我这样做是因为如果向我的endpoint发出了另一个api请求,并且使用了第一个请求中的一些名称,我希望重用它。因此,如果它在第一个队列中,我将对该任务调用await

当一个任务完成时,我需要知道没有其他人在任务中等待该用户,在这种情况下,将其从第一个队列中删除。此外,如果客户机断开连接,它应该删除对该客户机的用户部分的监视。

有人知道这是不是一个好方法吗?

共有1个答案

屠浩
2023-03-14

由于它是并行的,您马上就知道您可能需要使用system.collections.concurrent,而且由于您需要键/值查找(用户标识符/HTTP响应),您需要一个ConcurrentDictionary。而且由于有一个供所有用户使用的公共缓存,您将希望将其存储在一个静态变量中,该变量对所有线程和所有HTTP请求都可用。

这里有一个简单的例子:

public class MyCacheClass
{
    //Store the list of users/requests
    static private ConcurrentDictionary<string, Task<HttpResponseMessage>> _cache = new ConcurrentDictionary<string, Task<HttpResponseMessage>>();

    //Get from the ConcurrentDictionary or add if it's not there
    public async Task<HttpResponseMessage> GetUser(string key)
    {
        return await _cache.GetOrAdd(key, GetResponse(key));
    }

    //You just to implement this method, potentially in a subclass, to get the data
    protected virtual async Task<HttpResponseMessage> GetResponse(string key)
    {
        var httpClient = new HttpClient();
        var url = string.Format(@"http://www.google.com?q={0}", key);
        return await httpClient.GetAsync(url);
    }
}

然后要获取一个用户的信息,只需调用:

var o = new MyCacheClass();
var userInfo = await o.GetUser(userID);

注意:如果您要在生产系统上使用这样的代码,您可能会考虑在一段时间后或缓存达到一定大小时添加一些清除或修剪缓存的方法。否则,您的解决方案可能无法按您需要的方式扩展。

 类似资料:
  • 问题内容: 列表理解和映射计算都应该(至少在理论上)相对容易并行化:列表理解内的每个计算都可以独立于所有其他元素的计算来完成。例如在表达式中 每个x * x计算都可以(至少在理论上)并行完成。 我的问题是:是否有任何Python模块/ Python实施/ Python编程技巧可并行化列表理解计算(以便使用所有16​​/32 / …内核或将计算分布在计算机网格或在云上)? 问题答案: 正如Ken所说

  • 本文向大家介绍如何在Windows中的Eclipse上设置C / C ++?,包括了如何在Windows中的Eclipse上设置C / C ++?的使用技巧和注意事项,需要的朋友参考一下 步骤1-安装MinGW GCC或Cygwin GCC 要将Eclipse用于C / C ++编程,您需要一个C / C ++编译器。在Windows上,您可以安装MinGW GCC或Cygwin GCC。如果不确

  • 当我使用spark API运行类似的代码时,它在许多不同的(分布式)作业中运行,并且成功运行。当我运行它时,我的代码(应该做与Spark代码相同的事情),我得到一个堆栈溢出错误。知道为什么吗? 代码如下: 我相信我正在使用与spark相同的所有并行化工作,但它对我不起作用。任何关于使我的代码分发/帮助了解为什么在我的代码中发生内存溢出的建议都将是非常有帮助的

  • 问题内容: 如何设置一个计时器(例如2分钟)尝试连接数据库,然后在连接中出现任何问题时引发异常? 问题答案: 因此,答案的第一部分是如何做主题所要求的,因为这是我最初对它的解释方式,并且似乎有人发现有所帮助。此后,问题得到了澄清,我已经扩展了答案以解决该问题。 设定计时器 首先,你需要创建一个计时器(我在java.util这里使用版本): .. 要执行任务,请执行以下操作: 要在持续时间之后重复执

  • 问题内容: 这个问题已经在这里有了答案 : 9年前关闭。 可能的重复项: 在MS SQL Server 2005中模拟group_concat MySQL函数? SQL Server中的Concat组 我正在尝试编写将行合并在一起的SQL查询。我需要它通过ID#将未指定数量的行组合在一起,但将它们的地址连接起来,例如说成一个单元格。 说我们有 我想得到 每个ID的地址数量可以变化。一些ID具有1,

  • 问题说明 我需要一次发送多个API调用。 我有三个不同的 API endpoint,如下所示,所有这些endpoint都需要尽快调用。这一切都是相互独立的。 我所尝试的 我试着这样: 这里如何实现并行?