periodic-task 相关问题


在 C# 中将 Task<T> 转换为 Task<object>,无需 T

我有一个充满扩展方法的静态类,其中每个方法都是异步的并返回一些值 - 像这样: 公共静态类 MyContextExtensions{ 公共静态异步任务 我有一个充满扩展方法的静态类,其中每个方法都是异步的并返回一些值 - 像这样: public static class MyContextExtensions{ public static async Task<bool> SomeFunction(this DbContext myContext){ bool output = false; //...doing stuff with myContext return output; } public static async Task<List<string>> SomeOtherFunction(this DbContext myContext){ List<string> output = new List<string>(); //...doing stuff with myContext return output; } } 我的目标是能够从另一个类中的单个方法调用这些方法中的任何一个,并将其结果作为对象返回。它看起来像这样: public class MyHub: Hub{ public async Task<object> InvokeContextExtension(string methodName){ using(var context = new DbContext()){ //This fails because of invalid cast return await (Task<object>)typeof(MyContextExtensions).GetMethod(methodName).Invoke(null, context); } } } 问题是转换失败。我的困境是我无法将任何类型参数传递给“InvokeContextExtension”方法,因为它是 SignalR 中心的一部分并且由 javascript 调用。在某种程度上,我不关心扩展方法的返回类型,因为它只会序列化为 JSON 并发送回 javascript 客户端。但是,我确实必须将 Invoke 返回的值转换为任务才能使用等待运算符。我必须为该“任务”提供一个通用参数,否则它将把返回类型视为 void。因此,这一切都归结为如何成功地将具有通用参数 T 的任务转换为具有对象通用参数的任务,其中 T 表示扩展方法的输出。 您可以分两步完成 - await使用基类执行任务,然后使用反射或dynamic收获结果: using(var context = new DbContext()) { // Get the task Task task = (Task)typeof(MyContextExtensions).GetMethod(methodName).Invoke(null, context); // Make sure it runs to completion await task.ConfigureAwait(false); // Harvest the result return (object)((dynamic)task).Result; } 这是一个完整的运行示例,它将上述通过反射调用 Task 的技术置于上下文中: class MainClass { public static void Main(string[] args) { var t1 = Task.Run(async () => Console.WriteLine(await Bar("Foo1"))); var t2 = Task.Run(async () => Console.WriteLine(await Bar("Foo2"))); Task.WaitAll(t1, t2); } public static async Task<object> Bar(string name) { Task t = (Task)typeof(MainClass).GetMethod(name).Invoke(null, new object[] { "bar" }); await t.ConfigureAwait(false); return (object)((dynamic)t).Result; } public static Task<string> Foo1(string s) { return Task.FromResult("hello"); } public static Task<bool> Foo2(string s) { return Task.FromResult(true); } } 一般来说,要将 Task<T> 转换为 Task<object>,我会简单地采用简单的连续映射: Task<T> yourTaskT; // .... Task<object> yourTaskObject = yourTaskT.ContinueWith(t => (object) t.Result); (文档链接在这里) 但是,您实际的具体需求是 通过反射调用 Task 并获取其(未知类型)结果 。 为此,您可以参考完整的dasblinkenlight的答案,它应该适合您的具体问题。 我想提供一个实现,恕我直言,这是早期答案的最佳组合: 精确的参数处理 无动态调度 通用扩展方法 给你: /// <summary> /// Casts a <see cref="Task"/> to a <see cref="Task{TResult}"/>. /// This method will throw an <see cref="InvalidCastException"/> if the specified task /// returns a value which is not identity-convertible to <typeparamref name="T"/>. /// </summary> public static async Task<T> Cast<T>(this Task task) { if (task == null) throw new ArgumentNullException(nameof(task)); if (!task.GetType().IsGenericType || task.GetType().GetGenericTypeDefinition() != typeof(Task<>)) throw new ArgumentException("An argument of type 'System.Threading.Tasks.Task`1' was expected"); await task.ConfigureAwait(false); object result = task.GetType().GetProperty(nameof(Task<object>.Result)).GetValue(task); return (T)result; } 您不能将 Task<T> 转换为 Task<object>,因为 Task<T> 不是协变的(也不是逆变的)。最简单的解决方案是使用更多反射: var task = (Task) mi.Invoke (obj, null) ; var result = task.GetType ().GetProperty ("Result").GetValue (task) ; 这很慢且效率低下,但如果不经常执行此代码则可用。顺便说一句,如果您要阻塞等待其结果,那么异步 MakeMyClass1 方法有什么用呢? 另一种可能性是为此目的编写一个扩展方法: public static Task<object> Convert<T>(this Task<T> task) { TaskCompletionSource<object> res = new TaskCompletionSource<object>(); return task.ContinueWith(t => { if (t.IsCanceled) { res.TrySetCanceled(); } else if (t.IsFaulted) { res.TrySetException(t.Exception); } else { res.TrySetResult(t.Result); } return res.Task; } , TaskContinuationOptions.ExecuteSynchronously).Unwrap(); } 它是非阻塞解决方案,将保留任务的原始状态/异常。 最有效的方法是自定义等待者: struct TaskCast<TSource, TDestination> where TSource : TDestination { readonly Task<TSource> task; public TaskCast(Task<TSource> task) { this.task = task; } public Awaiter GetAwaiter() => new Awaiter(task); public struct Awaiter : System.Runtime.CompilerServices.INotifyCompletion { System.Runtime.CompilerServices.TaskAwaiter<TSource> awaiter; public Awaiter(Task<TSource> task) { awaiter = task.GetAwaiter(); } public bool IsCompleted => awaiter.IsCompleted; public TDestination GetResult() => awaiter.GetResult(); public void OnCompleted(Action continuation) => awaiter.OnCompleted(continuation); } } 具有以下用法: Task<...> someTask = ...; await TaskCast<..., object>(someTask); 这种方法的局限性在于结果不是 Task<object> 而是一个可等待的对象。 我根据dasblinkenlight的回答做了一个小小的扩展方法: public static class TaskExtension { public async static Task<T> Cast<T>(this Task task) { if (!task.GetType().IsGenericType) throw new InvalidOperationException(); await task.ConfigureAwait(false); // Harvest the result. Ugly but works return (T)((dynamic)task).Result; } } 用途: Task<Foo> task = ... Task<object> = task.Cast<object>(); 这样您就可以将 T 中的 Task<T> 更改为您想要的任何内容。 对于最佳方法,不使用反射和动态丑陋语法,也不传递泛型类型。我将使用两种扩展方法来实现这个目标。 public static async Task<object> CastToObject<T>([NotNull] this Task<T> task) { return await task.ConfigureAwait(false); } public static async Task<TResult> Cast<TResult>([NotNull] this Task<object> task) { return (TResult) await task.ConfigureAwait(false); } 用途: Task<T1> task ... Task<T2> task2 = task.CastToObject().Cast<T2>(); 这是我的第二种方法,但不推荐: public static async Task<TResult> Cast<TSource, TResult>([NotNull] this Task<TSource> task, TResult dummy = default) { return (TResult)(object) await task.ConfigureAwait(false); } 用途: Task<T1> task ... Task<T2> task2 = task.Cast((T2) default); // Or Task<T2> task2 = task.Cast<T1, T2>(); 这是我的第三种方法,但是不推荐:(类似于第二种) public static async Task<TResult> Cast<TSource, TResult>([NotNull] this Task<TSource> task, Type<TResult> type = null) { return (TResult)(object) await task.ConfigureAwait(false); } // Dummy type class public class Type<T> { } public static class TypeExtension { public static Type<T> ToGeneric<T>(this T source) { return new Type<T>(); } } 用途: Task<T1> task ... Task<T2> task2 = task.Cast(typeof(T2).ToGeneric()); // Or Task<T2> task2 = task.Cast<T1, T2>(); 将 await 与动态/反射调用混合使用并不是一个好主意,因为 await 是一条编译器指令,它会围绕调用的方法生成大量代码,并且使用更多反射来“模拟”编译器工作并没有真正的意义,延续、包装等 因为您需要的是在运行时管理代码,然后忘记在编译时工作的 asyc await 语法糖。重写 SomeFunction 和 SomeOtherFunction 而不使用它们,并在运行时创建的您自己的任务中开始操作。您将得到相同的行为,但代码非常清晰。


为什么 Apache IoTDB 在插入时间戳时报告 `WrappedthreadPoolExecutor` 错误?

这个错误的原因是什么?错误 o.a,i.c.c,t。 WrappedthreadPoolExecutor:111 - 线程池 org.apache 中出现异常。 iotdb.threadpool:type=Compaction-Sub-Task,然后它报告我去...


React Native Reanimated 错误:任务 ':Task :react-native-reanimated:prepareBoost FAILED' 执行失败

我尝试在 Android 模拟器上运行应用程序,但遇到了阻止程序。该问题似乎源于此软件包,导致应用程序无法运行。 这是正在寻找的包的版本...


Laravel 购物车页面,表单内有一个表单,用于处理删除和提交数据更新数据库

我有一个购物车页面,表格内有一个表格,也许你可以建议我应该做什么? 根据图片,我给出的蓝色圆圈是一个表格 我的刀片代码 我有一个购物车页面,表格内有一个表格,也许你可以建议我应该做什么?根据图片我给出的蓝色圆圈是一个表格我的刀片代码<table class="table"> <thead> <tr> <th scope="col">No</th> <th scope="col">Nama Barang</th> <th scope="col">Quantity</th> <th scope="col">Action</th> </tr> </thead> <tbody> @php $no = 1; @endphp @forelse ($permintaans as $b) <tr> <td>{{ $no ++ }}</td> <td> {{ $b->nama_kategori }} {{ $b->nama_atk }} </td> <td> <form action="{{ route('permintaan.update', $b->id) }}" method="POST" style="display: inline-block;"> @csrf @method('PUT') <div class="input-group input-group-sm mb-3"> <input type="number" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-sm" name="satuan_permintaan" min="0" max={{ $b->stok }} required> <span class="input-group-text" id="inputGroup-sizing-sm">{{ $b->subsatuan_atk }}</span> </div> </td> <td> <form action="{{ route('permintaan.destroy', $b->id) }}" method="POST" style="display: inline-block;"> @csrf @method('DELETE') <button type="submit" class="btn custom2-btn"><svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="red" class="bi bi-trash" viewBox="0 0 16 16"> <path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0z"/> <path d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4zM2.5 3h11V2h-11z"/> </svg></button> </form> </td> </tr> @empty @endforelse </tbody> </table> 我的控制器public function store(Request $request) { $task = new Permintaan(); $task->atk_id = $request->input('atk_id'); $task->proses = 'Proses'; if (Permintaan::where('atk_id', $task->atk_id)->exists()){ return redirect('/atk/permintaan')->with(['info' => 'ATK Sudah Dalam Permintaan']); } else{ $task->save(); return redirect()->route('permintaan.index'); } } public function destroy($id) { $permintaan = Permintaan::find($id); $permintaan->delete(); return redirect()->route('permintaan.index'); } 我要处理删除并提交数据更新数据库 在开始销毁表单之前关闭更新表单第一个表单标签(缺少)。


MVC ASP.NET Core Identity,创建登录、注册操作。 AuthController

公共类AuthController:控制器 { SignInManager _signInManager { 获取; } UserManager _userManager { 获取; } 角色管理器 public class AuthController : Controller { SignInManager<AppUser> _signInManager { get; } UserManager<AppUser> _userManager { get; } RoleManager<IdentityRole> _roleManager { get; } public AuthController(SignInManager<AppUser> signInManager, UserManager<AppUser> userManager, RoleManager<IdentityRole> roleManager) { _signInManager = signInManager; _userManager = userManager; _roleManager = roleManager; } public IActionResult Login() { return View(); } [HttpPost] public async Task<IActionResult> Login(string? returnUrl,LoginVM vm) { AppUser user; if (!ModelState.IsValid) { return View(vm); } if (vm.UsernameOrEmail.Contains("@")) { user = await _userManager.FindByEmailAsync(vm.UsernameOrEmail); } else { user = await _userManager.FindByNameAsync(vm.UsernameOrEmail); } if (user == null) { ModelState.AddModelError("", "Username or password is wrong"); return View(vm); } var result = await _signInManager.PasswordSignInAsync(user, vm.Password, vm.IsRemember, true); if (!result.Succeeded) { if (result.IsLockedOut) { ModelState.AddModelError("", "Too many attempts wait until " + DateTime.Parse(user.LockoutEnd.ToString()).ToString("HH:mm")); } else { ModelState.AddModelError("", "Username or password is wrong"); } return View(vm); } if (returnUrl != null) { return LocalRedirect(returnUrl); } return RedirectToAction("Index","Home"); } public IActionResult Register() { return View(); } [HttpPost] public async Task<IActionResult> Register(RegisterVM vm) { if (!ModelState.IsValid) { return View(vm); } var user = new AppUser { Fullname = vm.Fullname, Email = vm.Email, UserName = vm.Username }; var result = await _userManager.CreateAsync(user, vm.Password); if (!result.Succeeded) { foreach (var error in result.Errors) { ModelState.AddModelError("", error.Description); } return View(vm); } var roleResult = await _userManager.AddToRoleAsync(user, Roles.Member.ToString()); if (!roleResult.Succeeded) { ModelState.AddModelError("", "Something went wrong. Please contact admin"); return View(vm); } return View(); } public async Task<IActionResult> Logout() { await _signInManager.SignOutAsync(); return RedirectToAction("Index", "Home"); } public async Task<bool> CreateRoles() { foreach (var item in Enum.GetValues(typeof(Roles))) { if (!await _roleManager.RoleExistsAsync(item.ToString())) { var result = await _roleManager.CreateAsync(new IdentityRole { Name = item.ToString() }); if (!result.Succeeded) { return false; } } } return true; } } } 所以,我在代码中搞乱了登录、注册和注销,现在这个 RoleManager 的事情让我摸不着头脑。我只是想为我的管理员用户提供一些额外的权力,但我有点不知道该怎么做。如果您能用简单的语言解释步骤或需要进行哪些更改来帮助我,那就太棒了。 我的目标是让管理员用户在我的系统中体验更好,您对此的建议非常有用。尝试了解 RoleManager 的事情以及如何为我的管理员用户提供更多能力。您直接的帮助可能会对我解决这个问题产生很大的影响! 定义管理员角色 创建管理员用户 更新注册流程: var roleResult =等待_userManager.AddToRoleAsync(用户,vm.IsAdmin? Roles.Admin.ToString() : Roles.Member.ToString()); 使用管理员角色: [授权(角色=“管理员”)] 公共 IActionResult AdminDashboard() { // 特定于管理的逻辑 } 5.提升管理能力: if (User.IsInRole("管理员")) { // 特定于管理的逻辑 } 中间件配置: services.AddIdentity() .AddRoles() .AddEntityFrameworkStores(); 7.创建角色方法: 公共无效配置(IApplicationBuilder 应用程序,IHostingEnvironment env) { // 其他中间件配置 // Create roles during application startup var authController = new AuthController(/* inject your dependencies here */); authController.CreateRoles().GetAwaiter().GetResult(); }


© www.soinside.com 2019 - 2024. All rights reserved.