### Install Tooltip.js using npm or yarn Source: https://github.com/face-it/hangfire.tags/blob/main/samples/Hangfire.MvcApplication/Scripts/README.md Instructions for installing Tooltip.js using npm and yarn. Similar to Popper.js, these are the preferred installation methods. ```bash npm install tooltip.js --save ``` ```bash yarn add tooltip.js ``` -------------------------------- ### Install Popper.js using npm or yarn Source: https://github.com/face-it/hangfire.tags/blob/main/samples/Hangfire.MvcApplication/Scripts/README.md Instructions for installing Popper.js using popular package managers like npm and yarn. This is the recommended method for most projects. ```bash npm install popper.js --save ``` ```bash yarn add popper.js ``` -------------------------------- ### Configure Hangfire.Tags with SQL Server Storage Source: https://github.com/face-it/hangfire.tags/blob/main/README.md This snippet demonstrates how to configure Hangfire.Tags with SQL Server storage in a .NET Core application's Startup.cs file. It shows the basic setup and commented-out options for other database providers. ```csharp public void ConfigureServices(IServiceCollection services) { services.AddHangfire(config => { config.UseSqlServerStorage("connectionSting"); // config.UseTagsWithPostgreSql(); // config.UseTagsWithMySql(); // config.UseTagsWithRedis(); config.UseTagsWithSql(); }); } ``` -------------------------------- ### Configure Hangfire.Tags with Redis Storage (StackExchange) Source: https://context7.com/face-it/hangfire.tags/llms.txt This example illustrates the configuration of Hangfire.Tags using the StackExchange.Redis client for Redis storage. It establishes a connection to Redis and then configures Hangfire with the Redis storage and Hangfire.Tags, specifying the tag list style and cleanup behavior. ```csharp using Hangfire; using Hangfire.Redis.StackExchange; using Hangfire.Tags; using Hangfire.Tags.Redis.StackExchange; using StackExchange.Redis; public class Startup { public void ConfigureServices(IServiceCollection services) { var redis = ConnectionMultiplexer.Connect("localhost:6379"); services.AddHangfire(config => { config.UseRedisStorage(redis); config.UseTagsWithRedis(new TagsOptions { TagsListStyle = TagsListStyle.Dropdown, Clean = Clean.None }); }); services.AddHangfireServer(); } } ``` -------------------------------- ### Query Hangfire Tags using ITagsMonitoringApi Source: https://context7.com/face-it/hangfire.tags/llms.txt Details how to use the ITagsMonitoringApi to query and analyze tags across all Hangfire jobs. This includes getting tag counts, job counts for specific tags, job state distributions, searching for weighted tags, finding related tags, and retrieving jobs matching specific tags with pagination. ```csharp using Hangfire; using Hangfire.Tags; using Hangfire.Tags.Storage; public class TagsAnalytics { public void AnalyzeTags() { // Get the monitoring API from current job storage ITagsMonitoringApi monitoringApi = JobStorage.Current.GetTagsMonitoringApi(); // Get total number of unique tags long totalTags = monitoringApi.GetTagsCount(); Console.WriteLine($"Total unique tags: {totalTags}"); // Get job count for specific tags long errorJobs = monitoringApi.GetJobCount(new[] { "error" }); Console.WriteLine($"Jobs with 'error' tag: {errorJobs}"); // Get job count for tags with specific state long failedWithError = monitoringApi.GetJobCount(new[] { "error" }, "Failed"); Console.WriteLine($"Failed jobs with 'error' tag: {failedWithError}"); // Get job state distribution for tags var stateCount = monitoringApi.GetJobStateCount(new[] { "batch:001" }, maxTags: 50); foreach (var kvp in stateCount) { Console.WriteLine($" {kvp.Key}: {kvp.Value} jobs"); } // Search for weighted tags (for tag cloud display) var weightedTags = monitoringApi.SearchWeightedTags("batch"); foreach (var tag in weightedTags) { Console.WriteLine($"Tag: {tag.Tag}, Count: {tag.Amount}, Weight: {tag.Percentage:P}"); } // Find related tags var relatedTags = monitoringApi.SearchRelatedTags("order"); Console.WriteLine("Tags related to 'order':"); foreach (var related in relatedTags) { Console.WriteLine($" - {related}"); } // Get matching jobs with pagination var jobs = monitoringApi.GetMatchingJobs( tags: new[] { "priority:critical" }, from: 0, count: 10, stateName: null // All states ); Console.WriteLine($"Critical priority jobs (showing {jobs.Count}):"); foreach (var job in jobs) { Console.WriteLine($" Job ID: {job.Key}"); } } } ``` -------------------------------- ### Configure Hangfire.Tags with SQLite Storage Source: https://context7.com/face-it/hangfire.tags/llms.txt Configures Hangfire.Tags to use SQLite for lightweight deployments. This setup involves specifying the data source for the SQLite database and configuring tag options. ```csharp using Hangfire; using Hangfire.Storage.SQLite; using Hangfire.Tags; using Hangfire.Tags.SQLite; public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddHangfire(config => { config.UseSQLiteStorage("Data Source=hangfire.db;"); config.UseTagsWithSQLite(new TagsOptions { TagsListStyle = TagsListStyle.Dropdown, MaxTagLength = 100 }); }); services.AddHangfireServer(); } } ``` -------------------------------- ### Runtime Tagging via PerformContext in Hangfire Jobs Source: https://context7.com/face-it/hangfire.tags/llms.txt Add tags dynamically during job execution using `PerformContext.AddTags()` extension methods. This is useful for tagging jobs based on runtime conditions, processing results, or errors encountered. It allows for flexible categorization after the job has started. ```csharp using Hangfire; using Hangfire.Server; using Hangfire.Tags; using Hangfire.Tags.Attributes; [Tag("data-processing")] public class DataImportJob { public void ImportData(string source, PerformContext context, IJobCancellationToken token) { context.AddTags("source:" + source); try { var recordCount = 0; // Simulate data import for (int i = 0; i < 1000; i++) { token.ThrowIfCancellationRequested(); recordCount++; } // Add success tags based on results context.AddTags("success", $"records:{recordCount}"); context.AddTags("completed:" + DateTime.UtcNow.ToString("yyyy-MM-dd")); Console.WriteLine($"Imported {recordCount} records from {source}"); } catch (Exception ex) { // Add failure tags for easy filtering context.AddTags("failed", "error:" + ex.GetType().Name); throw; } } } // Enqueue the job BackgroundJob.Enqueue(x => x.ImportData("salesforce", null, null)); ``` -------------------------------- ### Basic Popper.js Initialization Source: https://github.com/face-it/hangfire.tags/blob/main/samples/Hangfire.MvcApplication/Scripts/README.md Demonstrates the basic usage of Popper.js by initializing a popper element relative to a reference element. It requires two DOM elements and an optional options object. ```javascript var reference = document.querySelector('.my-button'); var popper = document.querySelector('.my-popper'); var anotherPopper = new Popper( reference, popper, { // popper options here } ); ``` -------------------------------- ### Popper.js with onCreate and onUpdate Callbacks Source: https://github.com/face-it/hangfire.tags/blob/main/samples/Hangfire.MvcApplication/Scripts/README.md Shows how to use the `onCreate` and `onUpdate` callbacks in Popper.js to execute custom logic after the popper is initialized or updated. These callbacks receive data about the popper's state. ```javascript const reference = document.querySelector('.my-button'); const popper = document.querySelector('.my-popper'); new Popper(reference, popper, { onCreate: (data) => { // data is an object containing all the informations computed // by Popper.js and used to style the popper and its arrow // The complete description is available in Popper.js documentation }, onUpdate: (data) => { // same as `onCreate` but called on subsequent updates } }); ``` -------------------------------- ### Configure Hangfire.Tags with SQL Server Storage (GlobalConfiguration) Source: https://github.com/face-it/hangfire.tags/blob/main/README.md This snippet shows how to configure Hangfire.Tags using the GlobalConfiguration class, which is an alternative to the Startup.cs configuration. It includes options for different storage providers. ```csharp GlobalConfiguration.Configuration .UseSqlServerStorage("connectionSting") //.UseTagsWithPostgreSql() //.UseTagsWithMySql() //.UseTagsWithRedis(); .UseTagsWithSql(); ``` -------------------------------- ### Adding Tags to a Job using PerformContext Source: https://github.com/face-it/hangfire.tags/blob/main/README.md This snippet demonstrates how to add tags to a Hangfire job at runtime using the PerformContext extension method. The tag 'Hello, world!' is converted to 'hello-world'. ```csharp public void TaskMethod(PerformContext context) { context.AddTags("Hello, world!"); } ``` -------------------------------- ### Inheritance and Tag Combination in C# Source: https://context7.com/face-it/hangfire.tags/llms.txt Demonstrates how tags from base and derived classes are automatically combined for comprehensive job categorization in Hangfire. This allows for granular organization and filtering of background jobs. ```csharp using Hangfire; using Hangfire.Tags.Attributes; [Tag("base-job")] public class BaseJob { [Tag("base-method")] public virtual void Run() { Console.WriteLine("Base job running"); } } [Tag("derived-job")] public class DerivedJob : BaseJob { [Tag("derived-method")] public override void Run() { // This job gets all tags: "base-job", "derived-job", "base-method", "derived-method" base.Run(); Console.WriteLine("Derived job running"); } } [Tag("specialized-job")] public class SpecializedJob : DerivedJob { [Tag("specialized-method")] public override void Run() { // Gets: "base-job", "derived-job", "specialized-job", // "base-method", "derived-method", "specialized-method" base.Run(); Console.WriteLine("Specialized job running"); } } // Enqueue jobs with inherited tags BackgroundJob.Enqueue(x => x.Run()); // Tags: base-job, base-method BackgroundJob.Enqueue(x => x.Run()); // Tags: base-job, derived-job, base-method, derived-method BackgroundJob.Enqueue(x => x.Run()); // All six tags ``` -------------------------------- ### Configure Hangfire.Tags with Custom SQL Schema Options Source: https://github.com/face-it/hangfire.tags/blob/main/README.md This snippet illustrates how to configure Hangfire.Tags with SQL Server storage when a custom schema name is used. It also shows how to pass custom options to the UseTagsWithSql method. ```csharp var tagsOptions = new TagsOptions() { TagsListStyle = TagsListStyle.Dropdown }; var hangfireSqlOptions = new SqlServerStorageOptions { SchemaName = "MyCustomHangFireSchema", }; services.AddHangfire(hangfireConfig => hangfireConfig .SetDataCompatibilityLevel(CompatibilityLevel.Version_180) .UseColouredConsoleLogProvider() .UseSimpleAssemblyNameTypeSerializer() .UseRecommendedSerializerSettings() .UseSqlServerStorage("dbConnection", hangfireSqlOptions) .UseTagsWithSql(tagsOptions, hangfireSqlOptions) ); ``` -------------------------------- ### Declarative Tagging with TagAttribute in C# Source: https://context7.com/face-it/hangfire.tags/llms.txt Shows how to apply tags to all background jobs within a class by decorating the class with the `[Tag]` attribute. This simplifies tagging for related jobs. ```csharp using Hangfire; using Hangfire.Server; using Hangfire.Tags.Attributes; [Tag("email-service", "notifications")] public class EmailService { public void SendWelcomeEmail(string userId, PerformContext context) { // All jobs from this class automatically get "email-service" and "notifications" tags Console.WriteLine($"Sending welcome email to user {userId}"); } public void SendPasswordReset(string email, PerformContext context) { // This job also gets the class-level tags Console.WriteLine($"Sending password reset to {email}"); } } // Enqueue jobs - they automatically receive class-level tags BackgroundJob.Enqueue(x => x.SendWelcomeEmail("user-123", null)); BackgroundJob.Enqueue(x => x.SendPasswordReset("user@example.com", null)); ``` -------------------------------- ### Configure TagsOptions for Hangfire.Tags Source: https://context7.com/face-it/hangfire.tags/llms.txt Demonstrates how to customize the behavior and appearance of tags in Hangfire.Tags using the TagsOptions class. This includes setting tag length, colors, display style, and cleaning options. ```csharp using Hangfire.Tags; var options = new TagsOptions { // Maximum length for tags (backend may override with lower limit) MaxTagLength = 100, // Light mode colors TagColor = "#138496", // Background color TextColor = "#ffffff", // Text color // Dark mode colors DarkTagColor = "#17a2b8", DarkTextColor = "#ffffff", // Display style: LinkButton (tag cloud) or Dropdown (searchable list) TagsListStyle = TagsListStyle.Dropdown, // Tag cleaning: Default, Lowercase, Punctuation, or None // Default = Lowercase | Punctuation (lowercase + remove punctuation) // None = Keep tags exactly as provided Clean = Clean.Default }; services.AddHangfire(config => { config.UseSqlServerStorage("connectionString"); config.UseTagsWithSql(options); }); ``` -------------------------------- ### Custom applyStyle Modifier for Framework Integration Source: https://github.com/face-it/hangfire.tags/blob/main/samples/Hangfire.MvcApplication/Scripts/README.md Illustrates how to disable Popper.js's default `applyStyle` modifier and implement a custom one, `applyReactStyle`, for better integration with frameworks like React. This allows manual control over style application. ```javascript function applyReactStyle(data) { // export data in your framework and use its content to apply the style to your popper }; const reference = document.querySelector('.my-button'); const popper = document.querySelector('.my-popper'); new Popper(reference, popper, { modifiers: { applyStyle: { enabled: false }, applyReactStyle: { enabled: true, fn: applyReactStyle, order: 800, }, }, }); ``` -------------------------------- ### Parameter-Based Dynamic Tagging with TagAttribute Source: https://context7.com/face-it/hangfire.tags/llms.txt Utilize format strings within `TagAttribute` to create dynamic tags based on method parameters. This allows for job categorization that includes specific values from method arguments, such as customer IDs or regions. Ensure the format string placeholders match the parameter order. ```csharp using Hangfire; using Hangfire.Server; using Hangfire.Tags.Attributes; public class OrderProcessor { [Tag("order", "customer:{0}", "region:{1}")] public void ProcessOrder(string customerId, string region, PerformContext context) { // Tags: "order", "customer:cust-123", "region:us-west" Console.WriteLine($"Processing order for {customerId} in {region}"); } [Tag("shipment", "carrier:{0}")] public void ShipOrder(string carrier, string orderId, PerformContext context) { // Tags: "shipment", "carrier:fedex" Console.WriteLine($"Shipping order {orderId} via {carrier}"); } } // Enqueue with dynamic tags BackgroundJob.Enqueue(x => x.ProcessOrder("cust-123", "us-west", null)); BackgroundJob.Enqueue(x => x.ShipOrder("fedex", "order-456", null)); ``` -------------------------------- ### Declarative Tagging with TagAttribute on Methods and Classes Source: https://context7.com/face-it/hangfire.tags/llms.txt Apply tags to methods and classes using the `TagAttribute` for static categorization. Tags can be applied at the class level, method level, or both, providing a clear structure for job classification. This approach is useful for pre-defined job types. ```csharp using Hangfire; using Hangfire.Server; using Hangfire.Tags.Attributes; [Tag("reports")] public class ReportService { [Tag("daily", "sales")] public void GenerateDailySalesReport(PerformContext context) { // Gets "reports" (class), "daily", and "sales" (method) tags Console.WriteLine("Generating daily sales report..."); } [Tag("weekly", "inventory")] public void GenerateWeeklyInventoryReport(PerformContext context) { // Gets "reports" (class), "weekly", and "inventory" (method) tags Console.WriteLine("Generating weekly inventory report..."); } [Tag("critical", "financial")] [AutomaticRetry(Attempts = 5)] public void GenerateFinancialStatement(PerformContext context) { // Gets "reports", "critical", and "financial" tags Console.WriteLine("Generating financial statement..."); } } // Schedule recurring reports with automatic tags RecurringJob.AddOrUpdate("daily-sales", x => x.GenerateDailySalesReport(null), Cron.Daily); RecurringJob.AddOrUpdate("weekly-inventory", x => x.GenerateWeeklyInventoryReport(null), Cron.Weekly); ``` -------------------------------- ### Configure Hangfire.Tags with MongoDB Storage Source: https://context7.com/face-it/hangfire.tags/llms.txt Sets up Hangfire.Tags to use MongoDB as the storage backend. It configures migration strategies, connection checking, and tag list style. ```csharp using Hangfire; using Hangfire.Mongo; using Hangfire.Mongo.Migration.Strategies; using Hangfire.Mongo.Migration.Strategies.Backup; using Hangfire.Tags; using Hangfire.Tags.Mongo; using MongoDB.Driver; public class Startup { public void ConfigureServices(IServiceCollection services) { var mongoUrlBuilder = new MongoUrlBuilder("mongodb://localhost:27017/hangfire"); var mongoClient = new MongoClient(mongoUrlBuilder.ToMongoUrl()); var mongoStorageOptions = new MongoStorageOptions { MigrationOptions = new MongoMigrationOptions { MigrationStrategy = new MigrateMongoMigrationStrategy(), BackupStrategy = new CollectionMongoBackupStrategy() }, Prefix = "hangfire.mongo", CheckConnection = true }; services.AddHangfire(config => { config.UseMongoStorage(mongoClient, mongoUrlBuilder.DatabaseName, mongoStorageOptions); config.UseTagsWithMongo(new TagsOptions { TagsListStyle = TagsListStyle.Dropdown }, mongoStorageOptions); }); services.AddHangfireServer(); } } ``` -------------------------------- ### Configure Hangfire.Tags with MySQL Storage Source: https://context7.com/face-it/hangfire.tags/llms.txt This C# snippet shows how to set up Hangfire.Tags with a MySQL database. It defines MySQL-specific storage options, such as transaction isolation level and table prefix, and configures the tag display style for the Hangfire dashboard. ```csharp using Hangfire; using Hangfire.MySql; using Hangfire.Tags; using Hangfire.Tags.MySql; using System.Transactions; public class Startup { public void ConfigureServices(IServiceCollection services) { var mySqlOptions = new MySqlStorageOptions { TransactionIsolationLevel = IsolationLevel.ReadCommitted, QueuePollInterval = TimeSpan.FromSeconds(15), JobExpirationCheckInterval = TimeSpan.FromSeconds(15), PrepareSchemaIfNecessary = true, TablesPrefix = "hangfire" }; services.AddHangfire(config => { config.UseStorage(new MySqlStorage("Server=localhost;Database=hangfire;Uid=root;Pwd=secret;", mySqlOptions)); config.UseTagsWithMySql(new TagsOptions { TagsListStyle = TagsListStyle.Dropdown }, mySqlOptions); }); services.AddHangfireServer(); } } ``` -------------------------------- ### Runtime Tagging via Job ID Extension Method Source: https://context7.com/face-it/hangfire.tags/llms.txt Apply tags to jobs after their creation using the `string.AddTags()` extension method, which operates on the job ID. This is particularly useful for batch processing scenarios where multiple related jobs need to be tagged collectively or individually after they have been enqueued. ```csharp using Hangfire; using Hangfire.Tags; public class JobOrchestrator { public void EnqueueBatchWithTags(string batchId, List items) { var jobIds = new List(); foreach (var item in items) { // Enqueue job and capture ID var jobId = BackgroundJob.Enqueue(() => ProcessItem(item)); // Add tags to the job using the ID extension method jobId.AddTags("batch:" + batchId, "item:" + item, "queued"); jobIds.Add(jobId); } // Create a parent job that tracks the batch var parentJobId = BackgroundJob.Enqueue(() => CompleteBatch(batchId, jobIds.Count)); parentJobId.AddTags("batch:" + batchId, "parent", "batch-tracker"); Console.WriteLine($"Enqueued {jobIds.Count} jobs for batch {batchId}"); } public void ProcessItem(string item) { Console.WriteLine($"Processing {item}"); } public void CompleteBatch(string batchId, int count) { Console.WriteLine($"Batch {batchId} completed with {count} items"); } } // Usage var orchestrator = new JobOrchestrator(); orchestrator.EnqueueBatchWithTags("batch-001", new List { "item-a", "item-b", "item-c" }); ``` -------------------------------- ### Configure Hangfire.Tags to Use Dropdown for Tag List Style Source: https://github.com/face-it/hangfire.tags/blob/main/README.md This C# code snippet demonstrates how to configure the Hangfire.Tags library to display the tag list as a dropdown instead of the default tagcloud. It involves creating a TagsOptions object and setting the TagsListStyle property. This configuration is then applied using the UseTagsWithSql method. ```csharp var options = new TagsOptions() { TagsListStyle = TagsListStyle.Dropdown }; config.UseTagsWithSql(options); ``` -------------------------------- ### Configure Hangfire.Tags with PostgreSQL Storage Source: https://context7.com/face-it/hangfire.tags/llms.txt This code configures Hangfire.Tags to utilize PostgreSQL as its storage. It includes the necessary using statements and sets up Hangfire with PostgreSQL storage options, including job expiration and queue polling intervals, and customizes the tag display in the dashboard. ```csharp using Hangfire; using Hangfire.PostgreSql; using Hangfire.Tags; using Hangfire.Tags.PostgreSql; public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddHangfire(config => { config.UsePostgreSqlStorage("Host=localhost;Database=hangfire;Username=postgres;Password=secret;", new PostgreSqlStorageOptions { JobExpirationCheckInterval = TimeSpan.FromSeconds(15), QueuePollInterval = TimeSpan.FromTicks(1) }); config.UseTagsWithPostgreSql(new TagsOptions { TagsListStyle = TagsListStyle.LinkButton }); }); services.AddHangfireServer(); } } ``` -------------------------------- ### Adding Tags to a Job using Attributes Source: https://github.com/face-it/hangfire.tags/blob/main/README.md This snippet shows how to apply tags to a Hangfire job using the [Tag] attribute. Tags can be applied to the class or the method, or both. ```csharp [Tag("TaskMethod")] public void TaskMethod(PerformContext context) { .... } ``` -------------------------------- ### Retrieve Tags for a Hangfire Job Source: https://context7.com/face-it/hangfire.tags/llms.txt Explains how to retrieve all tags associated with a specific Hangfire job using its ID. It also shows how to check for the presence of specific tags or tags matching a pattern. This is useful for inspecting job metadata and making decisions based on tags. ```csharp using Hangfire; using Hangfire.Tags; public class JobInspector { public void InspectJob(string jobId) { // Get all tags for a job string[] tags = jobId.GetTags(); Console.WriteLine($"Job {jobId} has {tags.Length} tags:"); foreach (var tag in tags) { Console.WriteLine($" - {tag}"); } // Check for specific tags if (tags.Contains("priority:critical")) { Console.WriteLine("This is a critical priority job!"); } if (tags.Any(t => t.StartsWith("error:"))) { Console.WriteLine("This job has encountered errors."); } } public bool HasTag(string jobId, string tag) { return jobId.GetTags().Contains(tag); } } // Usage var inspector = new JobInspector(); inspector.InspectJob("123"); ``` -------------------------------- ### Custom Schema Configuration for Hangfire.Tags SQL Server Source: https://context7.com/face-it/hangfire.tags/llms.txt Configures Hangfire.Tags with custom database schema names for SQL Server storage. This allows for better organization of Hangfire tables within a larger database. ```csharp using Hangfire; using Hangfire.SqlServer; using Hangfire.Tags; using Hangfire.Tags.SqlServer; public class Startup { public void ConfigureServices(IServiceCollection services) { var tagsOptions = new TagsOptions { TagsListStyle = TagsListStyle.Dropdown, MaxTagLength = 100 }; var hangfireSqlOptions = new SqlServerStorageOptions { SchemaName = "MyCustomHangFireSchema", PrepareSchemaIfNecessary = true }; services.AddHangfire(config => { config.SetDataCompatibilityLevel(CompatibilityLevel.Version_180) .UseSimpleAssemblyNameTypeSerializer() .UseRecommendedSerializerSettings() .UseSqlServerStorage("Server=localhost;Database=MyApp;Integrated Security=true;", hangfireSqlOptions) .UseTagsWithSql(tagsOptions, hangfireSqlOptions); }); services.AddHangfireServer(); } } ``` -------------------------------- ### Configure Hangfire Tags with Redis StackExchange in .NET Core Source: https://github.com/face-it/hangfire.tags/blob/main/src/FaceIT.Hangfire.Tags.Redis.StackExchange/README.md This snippet demonstrates how to add Hangfire Tags and configure its Redis storage within the ConfigureServices method of a .NET Core application. It requires the Hangfire.Tags.Redis and Hangfire.RedisStackExchange packages. The configuration uses Redis for storage and enables tags functionality. ```csharp public void ConfigureServices(IServiceCollection services) { services.AddHangfireTagsRedisStackExchange(); services.AddHangfire((serviceProvider, configuration) => { config.UseRedisStorage(); config.UseTagsWithRedis(serviceProvider); }); } ``` -------------------------------- ### Remove Tags from Hangfire Jobs Source: https://context7.com/face-it/hangfire.tags/llms.txt Demonstrates how to remove tags from Hangfire jobs. This can be done during job execution by modifying the PerformContext or by directly manipulating tags for a given job ID. It's useful for managing job states and priorities. ```csharp using Hangfire; using Hangfire.Server; using Hangfire.Tags; using Hangfire.Tags.Attributes; [Tag("workflow")] public class WorkflowJob { public void ProcessWithStateTransitions(PerformContext context) { // Initial state context.AddTags("status:pending", "priority:high"); // Transition to processing context.RemoveTags("status:pending"); context.AddTags("status:processing"); // Simulate work Thread.Sleep(1000); // Transition to completed context.RemoveTags("status:processing", "priority:high"); context.AddTags("status:completed", "priority:normal"); Console.WriteLine("Workflow completed"); } } // Remove tags by job ID public void UpdateJobPriority(string jobId) { // Remove old priority tag jobId.RemoveTags("priority:low", "priority:normal", "priority:high"); // Add new priority jobId.AddTags("priority:critical"); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.