相关疑难解决方法(0)

Task.WaitAll挂起了ASP.NET中的多个等待任务

下面是我遇到问题的代码的简化版本.当我在控制台应用程序中运行它时,它按预期工作.所有查询都是并行运行的,并Task.WaitAll()在完成后返回.

但是,当此代码在Web应用程序中运行时,请求才会挂起.当我附加一个调试器并中断所有时,它表明执行正在等待Task.WaitAll().第一项任务已经完成,但其他任务从未完成.

我无法弄清楚它在ASP.NET中运行时挂起的原因,但在控制台应用程序中运行良好.

public Foo[] DoWork(int[] values)
{
    int count = values.Length;
    Task[] tasks = new Task[count];

    for (int i = 0; i < count; i++)
    {
        tasks[i] = GetFooAsync(values[i]);
    }

    try
    {
        Task.WaitAll(tasks);
    }
    catch (AggregateException)
    {
        // Handle exceptions
    }

    return ...
}

public async Task<Foo> GetFooAsync(int value)
{
    Foo foo = null;

    Func<Foo, Task> executeCommand = async (command) =>
    {
        foo = new Foo();

        using (SqlDataReader reader = await command.ExecuteReaderAsync())
        {
            ReadFoo(reader, foo); …
Run Code Online (Sandbox Code Playgroud)

c# asp.net task-parallel-library async-await

26
推荐指数
1
解决办法
9285
查看次数

Asp.net SynchronizationContext锁定HttpApplication以实现异步延续?

这个评论斯蒂芬·克利里这样说:

AspNetSynchronizationContext是最奇怪的实现.它将处理Post为同步而非异步,并使用锁定一次执行一个委托.

同样,他在同步上下文中写的文章与该评论中的链接表明:

从概念上讲,AspNetSynchronizationContext的上下文很复杂.在异步页面的生命周期中,上下文仅从ASP.NET线程池中的一个线程开始.异步请求启动后,上下文不包含任何线程.当异步请求完成时,执行其完成例程的线程池线程进入上下文.这些线程可能与发起请求的线程相同,但更可能是在操作完成时任何线程都是空闲的.

如果同一应用程序同时完成多个操作,AspNetSynchronizationContext将确保它们一次执行一个.它们可以在任何线程上执行,但该线程将具有原始页面的标识和文化.

挖掘反射器似乎验证了这一点,因为它HttpApplication在调用任何回调时需要锁定.

锁定app对象看起来像是可怕的东西.所以我的第一个问题:这是否意味着今天,整个应用程序的所有异步完成都会一次执行一个,即使是源自具有单独HttpContexts的单独线程上的单独请求的那些?对于任何100%使用异步页面(或MVC中的异步控制器)的应用程序来说,这不是一个巨大的瓶颈吗?如果没有,为什么不呢?我错过了什么?

此外,在.NET 4.5中,它看起来像是一个新的AspNetSynchronizationContext,旧的重命名LegacyAspNetSynchronizationContext,仅在UseTaskFriendlySynchronizationContext未设置新的应用程序设置时使用.问题2:新实现是否会改变这种行为?否则,我想通过同步上下文新的async/await支持编组完成,这种瓶颈会更频繁地被注意到.

这个论坛帖子的答案(从SO答案链接到这里)表明这里有一些根本改变的东西,但我想明确这是什么以及改进了什么行为,因为我们有一个.NET 4 MVC 3应用程序100%异步操作方法进行Web服务调用.

asp.net asp.net-mvc multithreading asynchronous async-await

13
推荐指数
1
解决办法
3830
查看次数

StackExchange.Redis死锁

StackExchange.Redis在我的Nancy应用程序中使用(SE.R).有一个全局ConnectionMultiplexer由Nancy TinyIoC通过构造函数参数自动传递,任何时候我尝试使用GetDatabase其中一个*Async方法(同步方法只在尝试了一个异步方法后才开始失败)我的应用程序死锁.

看看我的并行堆栈,看起来我有四个线程:

  1. 调用Result我的一个使用SE.R的任务的线程.(在堆栈上有很多Nancy东西,然后调用我的库使用SE.R,并调用Result.堆栈顶部是Monitor.Wait).
  2. 一个产生两个其他线程的线程.我认为这是由SE.R管理的.从堆栈开始Native to Managed Transition,ThreadHelper.ThreadStart在堆栈的顶部是ThreadHelper.ThreadStart_Context.
  3. 一个像这样粘在一起的小堆栈:
    • Monitor.Wait
    • Monitor.Wait
    • SocketManager.WriteAllQueues
    • SocketManager.cctor.AnonymousMethod__16
  4. 另一个小堆栈看起来像这样:
    • Managed to Native Transition
    • SocketManager.ReadImpl
    • SocketManager.Read
    • SocketManager.cctor.AnonymousMethod__19

我几乎可以肯定这是某种僵局.我甚至认为这可能与这个问题有关.但我不知道该怎么做.

ConnectionMultiplexer设置在南希IRegistrations用下面的代码:

var configOpts =  new ConfigurationOptions {
  EndPoints = {
    RedisHost,
  },
  Password = RedisPass,
  AllowAdmin = false,
  ClientName = ApplicationName,
  ConnectTimeout = 10000,
  SyncTimeout = 5000,
};
var mux = …
Run Code Online (Sandbox Code Playgroud)

task-parallel-library async-await stackexchange.redis

7
推荐指数
1
解决办法
2561
查看次数