- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
如果我只能访问任务,如何使用反射或任何其他方式创建和返回延续任务?
我需要一种方法让继续中的异常返回到原始调用者。据我所知,这只能通过返回延续任务而不是原始任务来完成。问题在于我不知道任务的结果类型,因此无法创建适当的延续任务。
编辑:我无法更改签名类型。我有许多返回 Task< TResult > 对象的接口(interface),不能指望客户端获得 Task< Object > 结果。这些接口(interface)是 WCF 契约。我想在“核心”逻辑方法完成后做一些额外的验证逻辑,并在需要时抛出异常。此异常必须传回客户端,但目前不会传回,因为我尚未返回继续任务。另外我事先不知道类型,因为我正在应用 postsharp 方面并使用 OnExit() 覆盖,这使我可以访问一个返回值,我知道它是一个 Task 但它可以是任意数量的 Task 对象,其中TResult 仅在运行时已知。
using System;
using System.Threading.Tasks;
namespace TaskContinueWith
{
internal class Program
{
private static void Main(string[] args)
{
try
{
Task<string> myTask = Interceptor();
myTask.Wait();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.ReadLine();
}
private static Task<string> Interceptor()
{
Task<string> task = CoreLogic(); //Ignore
Task unknownReturnType = task; //This is what I have access to. A Task object which can be one of numerous Task<TResult> types only known at runtime.
Task continuation = unknownReturnType.ContinueWith(
t =>
{
if(someCondition)
{
throw new Exception("Error");
}
return t.Result; //This obviously does not work since we don't know the result.
});
return continuation;
}
private static async Task<string> CoreLogic()
{
return "test";
}
}
}
表达问题的另一种方式。
如何更改 DoExtraValidation 以使其适用于任何 Task
using System;
using System.Threading.Tasks;
namespace TaskContinueWith
{
interface IServiceContract
{
Task<string> DoWork();
}
public class Servce : IServiceContract
{
public Task<string> DoWork()
{
var task = Task.FromResult("Hello");
return (Task<string>) DoExtraValidation(task);
}
private static Task DoExtraValidation(Task task)
{
Task returnTask = null;
if (task.GetType() == typeof(Task<string>))
{
var knownType = task as Task<string>;
returnTask = task.ContinueWith(
t =>
{
if(new Random().Next(100) > 50)
{
throw new Exception("Error");
}
return knownType.Result;
});
}
return returnTask;
}
}
internal class Program
{
private static void Main(string[] args)
{
try
{
IServiceContract myService = new Servce();
Task<string> myTask = myService.DoWork();
myTask.Wait();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.ReadLine();
}
}
}
最佳答案
听起来像是dynamic
的情况。我会尽量少用 dynamic
。首先我们定义一个强类型的助手:
static Task<TResult> SetContinuation<TResult>(Task<TResult> task)
{
return task.ContinueWith(
t =>
{
if(someCondition)
{
throw new Exception("Error");
}
return t.Result;
});
}
这个函数显然有效,但它需要TResult
才能知道。 dynamic
可填入:
Task continuation = SetContinuation((dynamic)unknownReturnType);
我刚刚测试了绑定(bind)在运行时是否有效。或者,您可以使用反射来调用帮助程序(使用 MethodInfo.MakeGenericMethod
等)。
关于c# - 在不知道 TResult 的情况下返回 Task.ContinueWith<TResult>(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17595915/
我正在研究撤消-重做实现,我希望其堆栈上的撤消或重做项目包含对某个 Func 的引用。其中 TResult本身就是一个 Func .重点是当Func从撤消堆栈调用,然后将返回值存储在重做堆栈中(反之亦
Func<>在 .NET 中非常方便。有没有一种方法可以指定参数类型并将结果值设置为 void?我想通过 void Write(string)作为参数。 最佳答案 Action - “封装一个接受单个
注意:请适本地重新标记和/或重命名 我有课,FooEnumerator ,它包装了一个 Foo并实现 IEnumerable . Foo s 代表树状数据结构,FooEnumerator枚举出来的s是
如果我只能访问任务,如何使用反射或任何其他方式创建和返回延续任务? 我需要一种方法让继续中的异常返回到原始调用者。据我所知,这只能通过返回延续任务而不是原始任务来完成。问题在于我不知道任务的结果类型,
我在运行我的应用程序时遇到此错误(尽管我的应用程序运行正常): C:\Users\dassa\Downloads\flutter_windows_2.2.3-stable\flutter\.pub-c
我正在加载一个程序集并调用一个静态方法,该方法将使用 MethodInfo.Invoke() 通过反射创建一个类型为“MyClass1”(此类型在运行时指定)的新对象。当该方法是普通同步方法时,这很好
首先,我知道我可以只定义两个重载的辅助方法来完成我需要的事情(或者甚至只定义两个具有不同名称的 Func<>),但它们只被一个公共(public)方法使用,所以我'我正在探索定义两个本地 Func<>
正如标题所说,“如何将 TResult 转换为 object 或 List 到 Expression 中?” public Task ExplicitLoadAsync(T entity, E
首先,foo 是一个 Func 对象。有可能做类似的事情 Func bar = ConvertFunction(foo); 从而将 Func 转换为 Func。 最佳答案 是的,这是可能的: Func
我非常喜欢使用 C# 5.0 异步编程。然而,有几个地方更新旧代码以与 TAP 模型保持一致给我带来了问题。 这是其中之一 - 我不确定为什么 Task 在 TResult 中不是协变的,但在尝试更新
我正在使用 Entity Framework 、ASP.NET 和 C#3.5我借用了以下代码,使用 GridView 中的 sortExpression 而不是实体的属性来进行排序: pub
如何使用“async Task”从方法返回数据。我尝试按照以下链接使用, How to handle return values in async function谁能给个答案? 使用的方法, Pub
根据documentation ValueTask ... Provides a value type that wraps a Task and a TResult, only one of whi
我承认这个问题是主观的,但我对社区的观点很感兴趣。我有一个缓存类,它采用 Func 类型的缓存加载器函数。 ,它用于从数据库中检索值并将其存储在缓存中。 public static class Cac
我有这个简单的代码,可以异步启动方法。它使用TCS以便使用Task包装代码。 Task DoWork() { var source = new TaskCompletionSource ();
我有两个类(它们保存在 RavenDB 中): public class Game { public int Id { get; set; } public int HomeTeamI
我不能使用 ToList()扩展方法。我使用的代码是, return this.Semesters.ToList() 上面代码中的'Semesters'是一个EntityCollection。这些
我有一个扩展类扩展 Func其签名如下所示: public static ITryAndReturnValue Try(this Func func, T arg, int retries) 我可以通
这个问题在这里已经有了答案: Await on a completed task same as task.Result? (2 个答案) 关闭 6 年前。 我写了一个小例子来在方法 TestMet
我有一个条件对象,如果它的值不为空,我将在其中将每个属性转换为一个函数。 public class TestClassCriteria { public bool? ColumnA { get
我是一名优秀的程序员,十分优秀!