[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"sanity-M86Y7GfoC_sq_p1nU30bodtMwc-6aizHUsFXs1ZPqZs":3,"sanity-GnehVl08MAiIfjMRADubfw0dn6ojFHw87Vlv4Cxd-Z0":210},{"data":4,"sourceMap":-1},{"latestPodcast":5,"latestReleases":14,"post":39,"recent":185},[6],{"_id":7,"publishedAt":8,"slug":9,"sponsored":12,"title":13},"d81860b7-7b72-4ba5-8ad5-3b77fd9a8e9b","2026-07-14T07:40:00.000Z",{"_type":10,"current":11},"slug","your-ai-is-only-as-responsible-as-you-are",null,"Your AI is only as responsible as you are",[15,21,27,33],{"_id":16,"publishedAt":17,"slug":18,"title":20},"eb5b66eb-9410-4329-83bb-22bbff39402a","2026-04-28T13:00:00.000Z",{"_type":10,"current":19},"turn-scattered-knowledge-into-trusted-intelligence","Turning scattered knowledge into trusted intelligence: Stack Internal 2026.3",{"_id":22,"publishedAt":23,"slug":24,"title":26},"369c2401-b62e-4a37-8ff8-bf603023ecad","2026-03-02T15:03:00.988Z",{"_type":10,"current":25},"what-s-new-at-stack-overflow-march-2026","What’s new at Stack Overflow: March 2026",{"_id":28,"publishedAt":29,"slug":30,"title":32},"5e9053a4-07ea-447c-91ea-29e0b6228537","2026-02-02T15:00:00.000Z",{"_type":10,"current":31},"what-s-new-at-stack-overflow-february-2026","What’s new at Stack Overflow: February 2026",{"_id":34,"publishedAt":35,"slug":36,"title":38},"a1b538eb-a8a6-46d0-80a1-ac70ec9bb935","2026-01-05T10:00:00.000-05:00",{"_type":10,"current":37},"what-s-new-at-stack-overflow-january-2026","What’s new at Stack Overflow: January 2026",{"_createdAt":40,"_id":41,"_rev":42,"_type":43,"_updatedAt":44,"author":45,"body":59,"comments":161,"dateUrl":162,"excerpt":163,"legacyBody":164,"product":12,"publishedAt":167,"slug":168,"sponsored":12,"tags":170,"title":184,"visible":161},"2023-05-25T09:36:57Z","wp-post-3191","dgl3SCUzppW3U2LvCoRupY","blogPost","2023-07-13T14:54:15Z",[46],{"_createdAt":47,"_id":48,"_rev":49,"_type":50,"_updatedAt":51,"avatar":52,"employee":54,"name":55,"role":56,"slug":57},"2023-05-23T16:27:18Z","wp-author-114","07ZbrKPSUrjrV4wQ6fam8u","blogAuthor","2023-08-29T11:49:01Z",{"_type":53},"image","former","Jeff Atwood","Co-founder",{"current":58},"jeffatwood",[60,80,100,118,134,142,150,153],{"_key":61,"_type":62,"children":63,"markDefs":78,"style":79},"c67d1f3262bb","block",[64,69,74],{"_key":65,"_type":66,"marks":67,"text":68},"c67d1f3262bb0","span",[],"As I work on the badge implementation for Stack Overflow, I needed a way to call the code that detects and awards the badges out of band. Traditionally this is done by something like ",{"_key":70,"_type":66,"marks":71,"text":73},"c67d1f3262bb1",[72],"code","cron",{"_key":75,"_type":66,"marks":76,"text":77},"c67d1f3262bb2",[]," or scheduled tasks. I'd rather have the code stay inside our current codebase, though.",[],"normal",{"_key":81,"_type":62,"children":82,"markDefs":96,"style":79},"2f340d269f46",[83,87,92],{"_key":84,"_type":66,"marks":85,"text":86},"2f340d269f460",[],"I asked on Twitter and got some good responses, everything from \"write a service\" to \"use threads\". I also got a link to ",{"_key":88,"_type":66,"marks":89,"text":91},"2f340d269f461",[90],"9daffa60cac2","Simulate a Windows Service using ASP.NET to run scheduled jobs",{"_key":93,"_type":66,"marks":94,"text":95},"2f340d269f462",[],". Now this is interesting -- it's just simple enough to work:",[97],{"_key":90,"_type":98,"href":99,"reference":12},"link","http:\u002F\u002Fwww.codeproject.com\u002FKB\u002Faspnet\u002FASPNETService.aspx",{"_key":101,"_type":62,"children":102,"level":115,"listItem":116,"markDefs":117,"style":79},"9be625f3c68e",[103,107,111],{"_key":104,"_type":66,"marks":105,"text":106},"9be625f3c68e0",[],"At startup, add an item to the ",{"_key":108,"_type":66,"marks":109,"text":110},"9be625f3c68e1",[72],"HttpRuntime.Cache",{"_key":112,"_type":66,"marks":113,"text":114},"9be625f3c68e2",[]," with a fixed expiration.",1,"number",[],{"_key":119,"_type":62,"children":120,"level":115,"listItem":116,"markDefs":133,"style":79},"a97fc8e9140d",[121,125,129],{"_key":122,"_type":66,"marks":123,"text":124},"a97fc8e9140d0",[],"When cache item expires, do your work, such as ",{"_key":126,"_type":66,"marks":127,"text":128},"a97fc8e9140d1",[72],"WebRequest",{"_key":130,"_type":66,"marks":131,"text":132},"a97fc8e9140d2",[]," or what have you.",[],{"_key":135,"_type":62,"children":136,"level":115,"listItem":116,"markDefs":141,"style":79},"1f1891db1fad",[137],{"_key":138,"_type":66,"marks":139,"text":140},"1f1891db1fad0",[],"Re-add the item to the cache with a fixed expiration.",[],{"_key":143,"_type":62,"children":144,"markDefs":149,"style":79},"99be0a1f3b2f",[145],{"_key":146,"_type":66,"marks":147,"text":148},"99be0a1f3b2f0",[],"The code is quite simple, really:",[],{"_key":151,"_type":72,"code":152,"markDefs":12},"d20ae8a567dc","private static CacheItemRemovedCallback OnCacheRemove = null;\n\nprotected void Application_Start(object sender, EventArgs e)\n{\n    AddTask(\"DoStuff\", 60);\n}\n\nprivate void AddTask(string name, int seconds)\n{\n    OnCacheRemove = new CacheItemRemovedCallback(CacheItemRemoved);\n    HttpRuntime.Cache.Insert(name, seconds, null, \n        DateTime.Now.AddSeconds(seconds), Cache.NoSlidingExpiration,\n        CacheItemPriority.NotRemovable, OnCacheRemove);\n}\n\npublic void CacheItemRemoved(string k, object v, CacheItemRemovedReason r)\n{\n    \u002F\u002F do stuff here if it matches our taskname, like WebRequest\n    \u002F\u002F re-add our task so it recurs\n    AddTask(k, Convert.ToInt32(v));\n}",{"_key":154,"_type":62,"children":155,"markDefs":160,"style":79},"7102dd3d8611",[156],{"_key":157,"_type":66,"marks":158,"text":159},"7102dd3d86110",[],"Works well in my testing; badges are awarded every 60 seconds like clockwork for all users.",[],true,"2008\u002F07\u002F18","",{"code":165,"language":166},"\u003Cp>As I work on the badge implementation for Stack Overflow, I needed a way to call the code that detects and awards the badges out of band. Traditionally this is done by something like \u003Ccode>cron\u003C\u002Fcode> or scheduled tasks. I'd rather have the code stay inside our current codebase, though.\u003C\u002Fp>\n\u003Cp>I asked on Twitter and got some good responses, everything from \"write a service\" to \"use threads\". I also got a link to \u003Ca href=\"http:\u002F\u002Fwww.codeproject.com\u002FKB\u002Faspnet\u002FASPNETService.aspx\">Simulate a Windows Service using ASP.NET to run scheduled jobs\u003C\u002Fa>. Now this is interesting -- it's just simple enough to work:\u003C\u002Fp>\n\u003Col>\u003Cli>\n\u003Cp>At startup, add an item to the \u003Ccode>HttpRuntime.Cache\u003C\u002Fcode> with a fixed expiration.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>When cache item expires, do your work, such as \u003Ccode>WebRequest\u003C\u002Fcode> or what have you.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>Re-add the item to the cache with a fixed expiration.\u003C\u002Fli>\n\u003C\u002Fol>\u003Cp>The code is quite simple, really:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>private static CacheItemRemovedCallback OnCacheRemove = null;\n\nprotected void Application_Start(object sender, EventArgs e)\n{\n    AddTask(\"DoStuff\", 60);\n}\n\nprivate void AddTask(string name, int seconds)\n{\n    OnCacheRemove = new CacheItemRemovedCallback(CacheItemRemoved);\n    HttpRuntime.Cache.Insert(name, seconds, null, \n        DateTime.Now.AddSeconds(seconds), Cache.NoSlidingExpiration,\n        CacheItemPriority.NotRemovable, OnCacheRemove);\n}\n\npublic void CacheItemRemoved(string k, object v, CacheItemRemovedReason r)\n{\n    \u002F\u002F do stuff here if it matches our taskname, like WebRequest\n    \u002F\u002F re-add our task so it recurs\n    AddTask(k, Convert.ToInt32(v));\n}\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Works well in my testing; badges are awarded every 60 seconds like clockwork for all users. \u003C\u002Fp>","html","2008-07-18T12:00:00.000Z",{"current":169},"easy-background-tasks-in-aspnet",[171,179],{"_createdAt":172,"_id":173,"_rev":174,"_type":175,"_updatedAt":172,"slug":176,"title":178},"2023-05-23T16:43:21Z","wp-tagcat-background","9HpbCsT2tq0xwozQfkc4ih","blogTag",{"current":177},"background","Background",{"_createdAt":172,"_id":180,"_rev":174,"_type":175,"_updatedAt":172,"slug":181,"title":183},"wp-tagcat-company",{"current":182},"company","Company","Easy Background Tasks in ASP.NET",[186,192,198,204],{"_id":187,"publishedAt":188,"slug":189,"sponsored":12,"title":191},"76c9771b-34e6-4d98-8641-ecefc711f0ef","2026-07-06T15:23:34.559Z",{"_type":10,"current":190},"when-the-sensor-starts-thinking-snortml-agentic-ai-and-the-evolving-architecture-of-intrusion-detection","When the sensor starts thinking: SnortML, agentic AI, and the evolving architecture of intrusion detection",{"_id":193,"publishedAt":194,"slug":195,"sponsored":12,"title":197},"28e560af-f0aa-4d46-bd90-f435ad604aa7","2026-06-26T14:00:27.102Z",{"_type":10,"current":196},"paging-charity-how-can-engineering-leaders-avoid-becoming-bond-villains","Paging Charity! How can engineering leaders avoid becoming Bond villains?",{"_id":199,"publishedAt":200,"slug":201,"sponsored":12,"title":203},"4b22c2a3-3779-4966-93eb-5230391dbdce","2026-06-23T14:08:58.595Z",{"_type":10,"current":202},"your-ai-shipped-a-backend-that-boots-that-is-the-whole-problem","Your AI shipped a backend that boots. That is the whole problem.",{"_id":205,"publishedAt":206,"slug":207,"sponsored":12,"title":209},"5cf362e1-fe7b-45af-b69c-914731c6a052","2026-06-23T14:00:00.000Z",{"_type":10,"current":208},"the-2026-developer-survey-is-now-open-for-human-developers-only","The 2026 Developer Survey is now open (for human developers only)!",{"data":211,"sourceMap":-1},{"count":212,"lastTimestamp":213},3,"2023-05-25T09:45:54Z"]