- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
前言:我对 C# 中任务的底层实现不太了解,只了解它们的用法。为我在下面屠宰的任何东西道歉:
对于“我怎样才能开始一项任务但不等待它?”这个问题,我找不到一个好的答案。在 C# 中。更具体地说,即使任务的上下文已完成/销毁,我如何保证任务完成?
_ = someFunctionAsync();
对于启动和忘记任务来说是令人满意的,但是如果父级是 transient 的呢?如果任务无法在父任务之前完成怎么办?这在 Controller 方法中经常发生,以 _ = someFunctionAsync();
方式编写的任务可能会被取消。
Mã ví dụ:
[HttpGet]
public IActionResult Get()
{
_ = DoSomethingAsync();
return StatusCode(204);
}
为了解决这种取消,我创建了一个(相当愚蠢,imo)静态类来保留任务,以便他们有时间完成,但它不起作用,因为当父 Controller 被取消时任务被取消销毁:
public static class IncompleteTaskManager
{
private static ConcurrentBag _incompleteTasks = new();
private static event EventHandler? _onTaskCompleted;
public static void AddTask(Task t)
{
_onTaskCompleted += (sender, task) =>
{
_incompleteTasks = new ConcurrentBag(_incompleteTasks.Where(task => task != t));
};
_incompleteTasks.Add(CreateTaskWithRemovalEvent(t));
}
private static async Task CreateTaskWithRemovalEvent(Task t)
{
await t;
_onTaskCompleted?.Invoke(null, t);
}
}
另外,这看起来很复杂,感觉像是一个简单问题的糟糕解决方案。那么,我该怎么处理呢?什么是开始一项任务,忘记它,但保证它运行完成的正确方法?
编辑 1,以防有人建议:我读过帖子建议 _ = Task.Run(async () => await someFunctionAsync());
可能满足我的需求,但这也不是这样。虽然另一个线程运行该方法,但它的上下文也丢失了,并且该任务被取消,从而取消了子任务。
编辑 2:我意识到 Controller 示例不一定是最好的,因为我可以简单地编写不同的代码以立即响应,然后在处理 Controller 之前等待方法完成:
[HttpGet]
public async Task Get()
{
base.Response.StatusCode = 204;
await base.Response.CompleteAsync(); //Returns 204 to caller here.
await DoSomethingAsync();
}
1 Câu trả lời
这里有很多东西要解压。我可能会错过一些细节,但让我分享一些应该奠定良好基础的东西。
从根本上说,您所问的是如何在 ASP.NET 中创建后台任务。在 .NET 4.x 中,有一个 QueueBackgroundWorkItem为此目的创建的方法:它为您的任务提供了一个新的取消 token 来使用,而不是 Controller 操作提供的取消 token ,并将您切换到您提供的操作的不同上下文。
在 asp.net 核心中,有更强大(但更复杂)的 IHostedService
实现,包括 Bối cảnhDịch vụ
,但没有比 QueueBackgroundWorkItem 更简单的了。但是,the docs include an example展示了如何使用 Bối cảnhDịch vụ
来编写自己的实现。如果您使用他们的代码,您应该能够将 IBackgroundTaskQueue
注入(inject)您的 Controller 并调用 QueueBackgroundWorkItemAsync
以将后台任务排入队列。
这两种方法都需要有一些东西等待开始的任务。您永远无法真正“保证”完成任何给定任务,但它们至少可以更优雅地处理常见用例。例如,它们让您的托管环境(例如 IIS)知道某些东西仍在运行,因此它不会因为没有请求进入而自动关闭。如果托管环境被指示关闭,它可以发出信号这个事实通过取消 token ,您可以希望快速让您的任务进入安全状态以关闭而不是被随意中止。
它们还处理后台任务中未捕获异常的问题:异常被捕获并记录下来,而不是被静默吃掉或完全杀死应用程序。
这些都不能帮助您维护有关当前请求或用户等内容的上下文。这是明智的,因为重点是允许操作超出任何给定请求的范围。因此,您需要编写在这些操作中调用的任何代码,以不依赖 HttpContext/IHttpContextAccessor 或类似的任何有状态的东西。相反,在将后台任务排入队列之前从上下文中收集您需要的信息,并将该信息作为变量和参数传递给下游代码。无论如何,这通常是一种很好的做法,因为 HTTP 上下文是应该保留在 Controller 级代码中的职责,而您的大多数业务逻辑应该考虑业务级模型。通常最好尽可能避免依赖状态,以创建更可靠、可测试等的软件。
对于其他类型的应用程序,您还需要采用其他方法。通常最好对 [framework] background tasks
进行互联网搜索,其中 [framework]
是您正在使用的框架(例如 WPF)。不同的框架会有不同的限制。例如,如果您编写了一个控制台应用程序,该应用程序希望在没有命令行参数之外的任何交互的情况下运行,则从您的 Main 函数返回的 Task 可能需要等待您在其中启动的所有任务。另一方面,WPF 应用程序可能会在调用按钮单击等事件时启动多个后台任务,但有一些技巧可确保您在后台线程上执行 CPU 密集型工作,同时仅在 UI 线程上与 UI 元素交互.
关于c# - 创建、不等待和确保任务完成的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71899322/
Phương thức Task.WaitAll chờ tất cả các tác vụ, còn phương thức Task.WaitAny chờ một tác vụ. Làm sao để chờ đợi bất kỳ N tác vụ nào? Trường hợp sử dụng: Tải xuống một trang kết quả tìm kiếm, mỗi kết quả yêu cầu một tác vụ riêng để tải xuống và xử lý. Nếu tôi sử dụng WaitA
Tôi đang xem một số mã C# cũ trông như thế này: await Task.Run(() => { _logger.LogException(LogLevel.Error, mes
Làm thế nào để chạy tác vụ cron trong Linux? Sau phần Hỏi & Đáp này, tôi có tác vụ cron này để chạy - chỉ cần ghi một số thông tin vào tệp txt, // /var/www/cron.php $myfile = fo
Xin lỗi vì câu hỏi của người mới nhưng tôi muốn thực hiện ba nhiệm vụ theo trình tự và sử dụng hai vai trò trong sổ tay hướng dẫn: Nhiệm vụ Vai trò Nhiệm vụ Vai trò Nhiệm vụ Đây là những gì tôi có cho đến nay (nhiệm vụ, vai trò, nhiệm vụ): --- - tên: Nhiệm vụ Vai trò Nhiệm vụ ho
Tôi có một tác vụ tùy chỉnh phụ thuộc vào installDist - không chỉ để thực thi mà còn để xuất ra installDist: project.task('run', type: JavaExec, depends
Khi chạy lệnh gỡ cài đặt từ MSI được tạo bằng Wix, tôi cần phải buộc dừng tiến trình đang chạy ở chế độ nền trước khi nó cố gắng xóa bất kỳ tệp nào. Ứng dụng chính bao gồm một biểu tượng trên khay phản ánh quá trình giám sát các dịch vụ Windows cục bộ.
Tôi muốn viết một tác vụ Ant để tự động hóa tác vụ khởi động máy chủ và sau đó mở Internet Explorer bằng URL của ứng dụng của tôi. Rõ ràng là tôi phải thực hiện tác vụ startServer trước, sau đó là startApplic
Khi sử dụng ASP.NET 4.5, tôi đang cố gắng sử dụng cơ chế async/await mới. Tôi có một lớp triển khai IDataReader bao gồm trình đọc cụ thể của nhà cung cấp (như SqlDatareader). Tôi có một cái đơn giản
Sử dụng lệnh gradle tasks để nhận báo cáo về tất cả các tác vụ có sẵn. Có cách nào để thêm tham số vào lệnh này và lọc các tác vụ theo nhóm tác vụ không? Tôi muốn đưa ra một lệnh như gradle tasks group:Demo để lọc tất cả các tác vụ và
Có cách nào khác ngoài sshexec không? Nhiệm vụ thực hiện điều này là gì? Tôi biết bạn có thể sử dụng tác vụ sao chép tệp scp. Tuy nhiên, tôi cần thực hiện các thao tác khác, chẳng hạn như kiểm tra xem một số thư mục có tồn tại hay không rồi xóa chúng. Tôi muốn sử dụng một cái gì đó giống như điều kiện
Giả sử tôi có chuỗi - "D:\ApEx_Schema\Functions\new.sql@@\main\ONEVIEW_Integration\3" Tôi cần trích xuất nội dung sau vào biến diff - Tên tài liệu
Tôi cần viết một tác vụ ant để xác định xem một tệp có phải là tệp chỉ đọc hay không và sẽ thất bại nếu đúng như vậy. Tôi muốn tránh phải sử dụng bộ chọn tùy chỉnh để thực hiện việc này vì bản chất của hệ thống xây dựng của chúng tôi. Có ai có ý tưởng nào để thực hiện không? Tôi đang sử dụng ant 1.8 + ant-c
Đây là một vấn đề khoa học máy tính khá tổng quát và không dành riêng cho bất kỳ hệ điều hành hay khuôn khổ nào. Vì vậy, tôi hơi bối rối về chi phí liên quan đến việc chuyển đổi tác vụ trên nhóm luồng. Trong nhiều trường hợp, việc cung cấp cho mỗi tác vụ một luồng riêng là không hợp lý (chúng ta không muốn tạo quá nhiều luồng phần cứng).
Tôi đang sử dụng sổ tay hướng dẫn Ansible sau đây để tắt danh sách các máy chủ Ubuntu từ xa cùng một lúc: - hosts: my_hosts trở thành: yes remote_user: my_user
Làm thế nào để thay đổi thư mục làm việc hiện tại trong Ant? Tài liệu Ant không có nhiệm vụ nào và theo tôi, cách tốt nhất là không thay đổi thư mục làm việc hiện tại. Nhưng giả sử chúng ta vẫn muốn làm điều này – bạn sẽ làm thế nào? Cảm ơn bạn! Câu trả lời hay nhất
Có thể chạy cronjob ba ngày một lần không? Hoặc có thể là 10 lần một tháng. Câu trả lời tốt nhất là chạy ba ngày một lần - hoặc thường xuyên hơn vào cuối tháng. (Nếu tháng cuối cùng có 31 ngày, nó sẽ chạy trong 2 ngày liên tiếp.) 0 0 */3 * *
Làm thế nào để thực thi một công cụ được lưu trữ trong kho lưu trữ trong tác vụ Gradle? Trong trường hợp cụ thể của tôi, tôi đang xây dựng một ứng dụng Android bằng Gradle. Tôi đã thêm một tác vụ để mã hóa một số dữ liệu protobuf từ văn bản sang nhị phân
Dự án của tôi có cấu trúc sau: Root |- A |- C (phụ thuộc vào A) \- B (phụ thuộc vào A) Đối với tất cả các dự án con, chúng tôi sử dụng plugin của riêng mình để tạo tài nguyên: https://githu
Tôi đã thiết lập một cụm Hadoop với 4 nút, trong đó một nút đóng vai trò là NameNode cho HDFS cũng như nút chính Yarn. Nút này cũng là nút mạnh nhất. Bây giờ, tôi đã phân phối 2 tệp văn bản, một trên node01 (tên node) và một trên node
Cách tốt nhất để lưu trữ tác vụ cho nhiều người dùng trong TFS 2010 là gì? Tôi chỉ có thể giao một nhiệm vụ cho một người. (Ví dụ: Khi tôi lên kế hoạch demo cho tất cả các nhà phát triển) (Đây là dự án Scrum Msf Agile trong đó các nhiệm vụ là một phần của câu chuyện người dùng)
Tôi là một lập trình viên xuất sắc, rất giỏi!