Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 保证代码在单独的线程中完成_C#_Asp.net_.net_Multithreading_Task Parallel Library - Fatal编程技术网

C# 保证代码在单独的线程中完成

C# 保证代码在单独的线程中完成,c#,asp.net,.net,multithreading,task-parallel-library,C#,Asp.net,.net,Multithreading,Task Parallel Library,我已经编写了以下代码,以在不同的线程中执行一个方法,将一个新的工作卸载到新的线程中,这样我的主线程就可以快速处理其余的工作,并完成网页请求 public static Task ExecuteAsynchronously(Action action) { HttpContext currentContext = HttpContext.Current; System.Threading.Tasks.Task task = System.Threading.Tasks.Task.F

我已经编写了以下代码,以在不同的线程中执行一个方法,将一个新的工作卸载到新的线程中,这样我的主线程就可以快速处理其余的工作,并完成网页请求

public static Task ExecuteAsynchronously(Action action)
{
    HttpContext currentContext = HttpContext.Current;
    System.Threading.Tasks.Task task = System.Threading.Tasks.Task.Factory.StartNew(()
        =>
    {
        HttpContext.Current = currentContext;
        // Execute the desired action
        action();
    });
    return task;
}
我将从页面的页面加载事件从ASP.NET Web UI上下文调用该方法:

protected void Page_Load(object sender, EventArgs e)
{
    MethodA()

    Utility.ExecuteAsynchronously(() =>
    {
        // Do a long running task in separate thread
        MethodC()
    });

    MethodB()
}
i、 e

我对上述代码有以下问题:

  • 是否可以保证代码“在单独的线程中执行长时间运行的任务”将完成,或者在页面加载事件发生时可以中止 在使用
    方法A
    方法B
    方法完成工作之前完成

  • 我们甚至可以在
    ASP.NET
    上下文中使用
    Task.Factory.StartNew
    吗 保证我们在单独任务中分配的工作能够完成

  • 我们如何确保承担重/长操作负载(在某些情况下) 方法)远离
    ASP.NET
    主要是服务于 请求并确保单独线程中的代码将完成 当
    ASP.NET
    页面的请求被取消时,不会在这段时间内中止 以前完成的?这可能吗

  • 我们可以使用
    async wait
    来解决这个问题吗

  • 编辑:请注意,我不是说可以定期运行的后台任务

    假设操作的完成与请求无关,它独立于请求,但我希望任务能够确保完成,即使请求在它之前已经关闭/完成。如果我们省略wait关键字来同步调用executes,这个任务会完成吗

    在这种情况下,不能保证完工。我认为最好的方法是在单独的流程中运行该任务。你可以把它放在windows服务或其他任何地方。这样,请求所做的就是通知服务需要运行任务。这将允许您确保任务已完成,并将关注点从请求中分离出来

    public static Task ExecuteAsynchronously(Action action)
    {
        HttpContext currentContext = HttpContext.Current;
        System.Threading.Tasks.Task task = System.Threading.Tasks.Task.Factory.StartNew(()
            =>
        {
            HttpContext.Current = currentContext;
            // Execute the desired action
            action();
        });
        return task;
    }
    
    如果页面加载事件在
    MethodA
    MethodB
    方法中完成工作之前完成,是否可以保证代码
    在单独的线程中执行长时间运行的任务将完成,或者可以中止

    不,根本不能保证。此外,此任务的线程可能会被重新用于处理其他一些响应,而不会向您发出任何通知

    我们甚至可以在ASP.NET上下文中使用
    Task.Factory.StartNew
    ,并保证我们在单独任务中分配的工作能够完成吗

    如前所述,这些都不能保证。此外,
    StartNew
    是不应该使用的内部方法,
    Task.Run
    更可取,但在这种情况下没有帮助

    我们如何才能确保从ASP.NET主要线程(为请求提供服务)中移除沉重/漫长的操作负载(在某些方法中),并确保在ASP.NET页面的请求之前完成时,单独线程中的代码将完成,并且不会在这两个线程之间中止?这可能吗

    正如在评论中已经说过的,如果您不需要后台任务的结果,那么应该使用
    HostingEnvironment.QueueBackgroundWorkItem
    方法来完成此类工作

    我们可以用异步等待来解决这个问题吗

    ASP.NET
    根据定义已经是异步的。如果需要结果,不需要让另一个线程执行操作-只需在当前线程中运行代码即可


    现在,回到你真正的问题上来。您试图做的是将
    HttpContext.Current
    传递给后台任务,这是不推荐做的事情。发件人:

    调用者的消息不会流到工作项。例如,在后台线程中运行的代码无法访问常用的上下文属性如果需要信息,请将所关心的值复制到状态对象或闭包中,并将其传递给后台工作程序。

    不要传递实例本身,因为它不是线程安全的对象,甚至简单的属性获取程序(如)也可能抛出

    因此,您需要将代码更改为,并从中复制值

    其他相关资源:

    • 菲尔·哈克
    • 斯科特·汉斯曼
    • “答案是@StephenCleary

    Scott Hanselman撰写了一篇有用的博文,如果你阅读了我链接的博文,你就会意识到,无论背景任务的性质如何,有些解决方案都是适用的。你也会意识到你把重点放在了错误的风险上(例如,随机创建的任务或线程的最大风险是ASP.Net对它们没有真正的了解,因此可以随意回收应用程序池,这将杀死一个简单的任务)@Damien_不信者我无意冒犯你的编辑。“ASP.Net对它们没有真正的了解,因此可以随意回收应用程序池,这将杀死一个简单的任务”除了回收,如果我的请求在此之前完成,我的任务是否会被杀死?不,恰恰相反。正如我上面所说的,风险在于asp.net不了解此任务。更准确地说,没有任何东西将该任务链接到原始请求。好的,您的意思是,由于没有关于当前请求的新任务的知识,因此它可以自行完成,并且即使原始ASP.NET请求已完成,也不会死亡。感谢您分别回答每一点。您需要回答的主要问题是,操作的完成是否与请求相关,如果相关,则应等待。假设操作的完成与请求无关,它独立于请求,但我希望任务能够确保完成,即使请求在它之前已经关闭/完成。如果我们不等待,这项任务会完成吗