gpt4 book ai didi

c# - 在没有线程锁定的情况下通过同步 c# 调用异步

转载 作者:行者123 更新时间:2023-12-04 14:57:06 25 4
gpt4 key购买 nike

我制作了一个轻量级中介类库供内部使用。

查询可以映射到异步方法,而调用者对此一无所知。

public interface IMediator
{
TResult ExecuteQuery<TResult>(Query<TResult> query);
Task<TResult> ExecuteQueryAsync<TResult>(Query<TResult> query);

Task ExecuteCommandAsync(Command command);
Task<TResult> ExecuteCommandAsync<TResult>(Command<TResult> command);

void ExecuteCommand(Command command);
TResult ExecuteCommand<TResult>(Command<TResult> command);

void EnqueueTask(object task);
}

public abstract class Query<TResult> { }

public interface IQueryHandler<Query, TResult> where Query : Query<TResult>
{

TResult Handle(Query param);
}

public interface IAsyncQueryHandler<Query, TResult> where Query : Query<TResult>
{
Task<TResult> Handle(Query param);
}

当调用者处于同步线程中时,例如服务容器中的工厂方法,并且想要执行查询时,它不能使用 ExecuteQueryAsync 执行异步操作,而是使用查询的实际处理程序,实现IAsyncQueryHandler 是异步的。

所以我需要调用异步而不是同步。

我在注册时间做了一些反射(reflection),以实际弄清楚如何调用处理程序,我尝试了 .wait() 和 .result() 但我得到了线程锁。

当前代码如下所示。

private object AsyncSync(object service, object param)
{
dynamic t = Method.Invoke(service, new[] { param });
return t.GetAwaiter().GetResult();
}

Method 是来自反射的方法信息,service 是具有该方法的类的实例。

这段代码仍然给我线程死锁。

我怎样才能做到这一点,我需要查看任务工厂吗?有什么建议吗?

最佳答案

正如已经评论过的那样,最佳解决方案是一直使用 async……但有时这是不可能的。甚至微软也承认了这一点,在他们自己的框架中有一个工具可以同步运行 async 方法:

public static class AsyncHelper
{
private static readonly TaskFactory MyTaskFactory = new TaskFactory(CancellationToken.None,
TaskCreationOptions.None, TaskContinuationOptions.None, TaskScheduler.Default);

public static TResult RunSync<TResult>(Func<Task<TResult>> func)
{
var cultureUi = CultureInfo.CurrentUICulture;
var culture = CultureInfo.CurrentCulture;
return MyTaskFactory.StartNew(() =>
{
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = cultureUi;
return func();
}).Unwrap().GetAwaiter().GetResult();
}

public static void RunSync(Func<Task> func)
{
var cultureUi = CultureInfo.CurrentUICulture;
var culture = CultureInfo.CurrentCulture;
MyTaskFactory.StartNew(() =>
{
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = cultureUi;
return func();
}).Unwrap().GetAwaiter().GetResult();
}
}

https://github.com/aspnet/AspNetIdentity/blob/main/src/Microsoft.AspNet.Identity.Core/AsyncHelper.cs

你可以这样使用它:

public async Task<int> DoSomethingAsync()
{
await DoSomethingElseAsync();
return 0;
}

int result = AsyncHelper.RunSync(async () => await DoSomethingAsync());

我对此的感觉是,如果微软在他们自己的框架中这样做,那么我们也可以这样做。

关于c# - 在没有线程锁定的情况下通过同步 c# 调用异步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67720959/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com