为什么我的异步 ASP.NET Web API 控制器阻塞主线程?

2023-11-21

我有一个 ASP.NET Web API 控制器thought将异步操作。控制器设计为在第一个请求时休眠 20 秒,但立即为任何后续请求提供服务。所以我预计的时间表是这样的:

  1. 提出要求1。
  2. 提出要求2。
  3. 提出要求3。
  4. 要求 2 次退货。
  5. 请求 3 个退货。
  6. 等待约 20 秒。
  7. 请求 1 返回。

反而,no请求返回,直到请求 1 完成。

我可以确认(基于调试输出)入口线程和休眠线程 ID 是不同的。我特意用过TaskCreationOptions.LongRunning强制睡眠到一个单独的线程上,但应用程序仍然拒绝服务任何新请求,直到睡眠完成。

我是否遗漏了有关异步 Web API 控制器如何真正工作的一些基本知识?


public class ValuesController : ApiController
{
    private static bool _firstTime = true;

    public async Task<string> Get()
    {
        Debug.WriteLine("Entry thread id: {0}. Sync: {1}",
            Thread.CurrentThread.ManagedThreadId,
            SynchronizationContext.Current);
        await LongWaitAsync();
        return "FOOBAR";
    }

    private Task LongWaitAsync()
    {
        return Task.Factory.StartNew(() =>
            {
                if (_firstTime)
                {
                    _firstTime = false;
                    Debug.WriteLine("Sleepy thread id: {0}. Sync: {1}",
                        Thread.CurrentThread.ManagedThreadId,
                        SynchronizationContext.Current);
                    Thread.Sleep(20000);
                    Debug.WriteLine("Finished sleeping");
                }
            },
            CancellationToken.None,
            TaskCreationOptions.LongRunning,
            TaskScheduler.Default);
    }
}

这实际上与服务器无关,与客户端有关。 Chrome 和 Firefox 似乎都不想发送他们认为的“重复”请求,直到第一个请求得到响应。任一浏览器的单独“私有”会话将立即从第二个请求返回。 Internet Explorer 9 似乎没有表现出这种行为。

为了与客户端实现隔离,我将以下客户端放在一起。

class Program
{
    static void Main(string[] args)
    {
        var t1 = Task.Run(() => FetchData(1));
        var t2 = Task.Run(() => FetchData(2));
        var t3 = Task.Run(() => FetchData(3));

        var index = Task.WaitAny(t1, t2, t3);
        Console.WriteLine("Task {0} finished first", index + 1);

        Task.WaitAll(t1, t2, t3);
        Console.WriteLine("All tasks have finished");

        Console.WriteLine("Press any key");
        Console.ReadKey(true);
    }

    static void FetchData(int clientNumber)
    {
        var client = new WebClient();
        string data = client.DownloadString("http://localhost:61852/api/values");
        Console.WriteLine("Client {0} got data: {1}", clientNumber, data);
    }
}

它的输出是:

  1. 客户端2收到数据:“FOOBAR”(启动后几毫秒内)
  2. 客户端3收到数据:“FOOBAR”
  3. 任务2最先完成
  4. (在这里等待很久)
  5. 客户端1收到数据:“FOOBAR”
  6. 所有任务已完成
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我的异步 ASP.NET Web API 控制器阻塞主线程? 的相关文章

随机推荐

  • Visual Studio 不断要求将项目文件另存为

    我正在使用 VS 2010 最近我移动了一些文件并更改了路径等 该解决方案仍然可以正确编译 并且所有文件都可以毫无错误地加载 编译 但是几乎每次我在更改后进行编译时 它都会显示 另存为 对话框 并要求我保存其中一个项目 如果我尝试这样做 给
  • 使用pycharm调试,如何单步进入项目,而不进入django库

    想想这个场景 我调试 Django 项目并单步执行代码 进出 调试器有时会进入 Django 库或其他外部库 有谁知道如何防止调试器输入外部代码 或者至少迈出 大 一步让调试器返回到项目代码 有谁知道如何防止调试器输入外部代码 是的 德米特
  • Restangular 是否支持 withCredentials 选项和 cors 请求的其他选项?

    我正在谷歌搜索 但没有找到任何线索 矩形是否支持凭证选项以及 cors 请求的其他选项 我的意思是我可以在 cors 调用中使用它而没有任何问题吗 你能帮我吗 是的 它确实 您可以通过使用来设置它们setDefaultHttpFields
  • 不同 Logback 附加程序的特定于包的日志记录级别

    我有这个简单的 Logback 配置文件 其中包含两个附加程序和一些基于包名称的自定义日志记录级别
  • 点符号与 $elemMatch

    我有一个 unitScores 集合 其中每个文档都有一个 id 和一个文档数组 如下所示 id ObjectId 52134edd5b1c2bb503000001 scores userId ObjectId 5212bf3869bf35
  • PHPStorm 中是否可以实现 Ruby 语法高亮显示?

    I found this但老实说不确定如何安装它或它是否适用 谢谢 您链接的 Ruby 插件仅为 IntelliJ IDEA Ultimate 设计 它不适用于 PhpStorm 看这个答案更多细节 但是 可以使用 PhpStorm 中的
  • 在循环之前或循环中声明变量之间的区别?

    我一直想知道 一般来说 在循环之前声明一个一次性变量 而不是在循环内重复声明 是否会产生任何 性能 差异 A 完全没有意义 Java 中的示例 a 循环前声明 double intermediateResult for int i 0 i
  • 确定 GAM 平滑对象的导数

    我有一个非常简单的时间序列数据集 由单个变量的年平均值 AVERAGE 组成 我希望研究时间序列 趋势 分量的变化率 一阶导数 和加速度 二阶导数 以及相关的标准误差 我使用 MGCV 的 GAM 和 PREDICT 函数获得了 趋势 如下
  • 核心数据内存使用和内存警告

    我有这个问题 我在核心数据中有一个图像数据库 我获取所有图像 大约 80MB 并放入 NSMutableArray 中 对象被正确错误 NSArray fetchResults self managedObjectContext execu
  • Unity PerRequestLifetimeManager 在不同请求中重用对象

    我已经为我们的项目设置了 Unity 的依赖注入 该项目本身是一个同时使用 MVC 和 Web API 的 ASP NET 应用程序 对于数据库上下文 我正在使用PerRequestLifetimeManager 这样做是为了使业务逻辑的不
  • wpf - 我可以在 wpf 中使用 System.Drawing 吗?

    我正在将图像保存在数据库中 但是如何从数据库中检索该图像 当我尝试使用system drawing 它显示错误 一些人说我不能在wpf中使用system drwaing 甚至不能使用dll文件 我的代码是 private void btnS
  • 子 pom 中存在重复的artifactId

    我希望父 pom 为众多子 pom 定义一些要继承的属性 但是 当我尝试在父 pom 中的这些属性之一中使用 artifactId 时 它会在子项的有效 pom 中重复 下面是非常基本的示例 假设我拥有 poms 所需的所有有效字段 gro
  • ModelSim-Altera 错误

    我正在使用 Ubuntu Linux 14 04 LTS 和 Altera Quartus 15 0 网络版 由于许可错误 我很难模拟我的设计 我正在设计一个 LCD driverVEEK MT友晶科技的液晶触摸屏旋风 IV EP4CE11
  • 如何使用freopen_s函数

    为了从文本文件读取输入 我编写了以下代码 int main int x ifndef ONLINE JUDGE freopen input txt r stdin endif scanf d x printf d n x system pa
  • 为什么“git clone”不采用 refspec?

    看来很多人都去换了git clone与组合git init git fetch 这看起来相当愚蠢 不幸的是像 Jenkins 这样的工具不会为你做这件事 那么为什么 git clone 不像 git fetch 那样采用 refspec 呢
  • 如何在 Ruby 中获取 Enumerable 的第 n 个元素

    例如 要返回第 10 000 个质数 我可以编写 require prime Prime first 10000 last gt 104729 但是创建一个巨大的中间数组 只是为了检索它的最后一个元素感觉有点麻烦 鉴于 Ruby 是一种如此
  • 强制调用父方法

    是否有 或模式 强制调用父方法 我有一个像这样的抽象类 abstract class APrimitive public function validate Do some stuff that applies all classes th
  • 多个main方法有什么用?

    c 使我们能够使用方法定义多个类 Main方法是程序执行的入口点 那么为什么我们要拥有多个地方来执行程序呢 多个 main 方法相对于单个 main 方法有什么优点 Edit 示例 cs Class Example 1 public sta
  • 打字稿用只读属性初始化对象

    有没有办法初始化对象文字并同时声明其具有只读属性的接口 例如 let a readonly b 2 readonly c 3 您可以使用as const断言 let a b 2 c 3 as const typed as readonly
  • 为什么我的异步 ASP.NET Web API 控制器阻塞主线程?

    我有一个 ASP NET Web API 控制器thought将异步操作 控制器设计为在第一个请求时休眠 20 秒 但立即为任何后续请求提供服务 所以我预计的时间表是这样的 提出要求1 提出要求2 提出要求3 要求 2 次退货 请求 3 个