C# 如何确保端点不';如果一个方法是';它已经在运行了?

C# 如何确保端点不';如果一个方法是';它已经在运行了?,c#,asp.net,ashx,C#,Asp.net,Ashx,我有一个运行方法的端点。我想确保当我多次命中端点时,该方法在运行时不会被执行 我想我可以在线程池中的某个地方设置一个变量或者别的什么?我不知道如何着手调查这件事。一些线索将不胜感激 我的例子是: namespace Website.Import { public class ImportProducts : IHttpHandler { private static bool running = false; public void Process

我有一个运行方法的端点。我想确保当我多次命中端点时,该方法在运行时不会被执行

我想我可以在线程池中的某个地方设置一个变量或者别的什么?我不知道如何着手调查这件事。一些线索将不胜感激

我的例子是:

namespace Website.Import
{
    public class ImportProducts : IHttpHandler
    {
        private static bool running = false;
        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "application/json";

            if (running)
            {
                throw new Exception("Already running");
            }

            running = true;

            try
            {
                var repo = new MemoryRepository();

                var productImporter = new ProductImporter(repo);
                var groupImporter = new GroupImporter(repo);
                var discountImporter = new DiscountImporter(repo);
            }
            finally
            {
                running = false;
            }

            context.Response.Write("Done");

        }

        public bool IsReusable
        {
            get
            {
                return true;
            }
        }
    }
}

您可以创建一个锁对象,以确保操作不会并行运行

private static object lockObject = new object();

lock (lockObject)
{
    // your code
}
但可能存在一个问题:由于静态变量在所有会话中共享,因此该方法将为每个用户锁定

这种行为可能是故意的。如果要阻止所有会话的执行,则可以使用此代码。如果只想阻止此用户的执行,允许每个用户同时运行一次方法,则必须将对象放入会话存储中

如果您只想通知客户端它已经在运行,还可以抛出异常:

private static bool alreadyExecuting = false;

if (alreadyExecuting)
{
    throw new Exception("Already running");
}

alreadyExecuting = true;

try
{
    // your code
}
finally
{
    alreadyExecuting = false;
}

其他请求应该怎么办?他们应该返回错误吗?等待完成,然后轮到自己?等待完成,然后共享结果?还有什么吗?返回字符串消息会很理想,但老实说,这在我的情况下并不重要。@evaldasraiseutis您错过了评论的要点。这确实很重要,您所要求的是滥用HTTP的核心行为,并将最终导致IIS问题。首先,为什么假设请求将由同一台机器提供服务?在无法工作的负载平衡方案中,我知道安装程序正在单台服务器上运行。@evaldasraiseutis例如,如果要执行长时间运行的维护作业,锁定是最不重要的问题,因为IIS不喜欢长时间运行的请求。使用Hangfire解决问题。至少,将作业的状态存储在一些公共存储(数据库、Redis缓存等)中,以便所有服务器都知道作业的状态。这会引发错误还是等待锁定完成然后执行?我希望任何后续的端点点击都只返回字符串消息,如果它们无法运行该方法(因为该方法已经在运行),那么.axhx句柄的情况是否相同?嗯,它似乎不起作用。我已经在你的回答中添加了我的例子。如果我运行一次,然后立即再次运行,它会在两个选项卡上显示“完成”。请停止编辑我的文章以包含您的代码。它分散了我对通用解决方案的注意力。@evaldasraiseutis问题本身就是错误的。HTTP不是这样工作的。例如,您考虑过负载平衡吗?为什么要限制请求的数量?您试图解决的真正问题是什么?为什么您认为阻塞端点才是解决方案?如果要运行维护作业,请使用Hangfire或类似的库来执行。至少,检查作业的状态,而不是请求的状态