有一个同步处理程序和一个异步处理程序

Posted

技术标签:

【中文标题】有一个同步处理程序和一个异步处理程序【英文标题】:Have a synchronous handler and an asynchronous handler 【发布时间】:2018-06-08 23:44:04 【问题描述】:

请看下面的同步代码:

public class PersonHandler : IRequestHandler<Person, Person>
    
        public Task<Person> Handle(Person request, CancellationToken cancellationToken)
        
            request.ID = 1;
            request.Name = "Brian";
            request.Age = 53;
            return Task.FromResult(request);
        
    

以及下面的调用代码:

var response2 = mediator.Send(new Person());

这按预期工作。请看下面的异步代码:

public class PersonHandlerAsync : IRequestHandler<Person, Person>
    
        public async Task<Person> Handle(Person request, CancellationToken cancellationToken)
        
            request.ID = 1;
            request.Name = "Brian";
            request.Age = 53;
            var result = await Task.FromResult(request);
            await Task.Delay(30000);
            return result;
        
    

以及下面的调用代码:

var response = Task.Run(() => mediator.Send(new Person()));

此代码按预期工作。

同一个类(Person)是否可以有两个处理程序,即一个同步另一个异步?如果我将两个处理程序类都放在我的代码中,那么 mediator.send 行,即 mediator.Send(new Person());Task.Run(() =&gt; mediator.Send(new Person())); 都会调用同步方法。

如何告诉 mediatr,使用哪个处理程序类?即同步调用的 PersonH​​andler 和异步调用的 PersonH​​andlerAsync。

【问题讨论】:

您使用的是什么版本的 Mediatr?: @Alex,4.0.1。它似乎没有此处文档中所述的 IAsyncRequestHandler:github.com/jbogard/MediatR/wiki(页面底部)。 @Alex,你有什么建议吗?谢谢。 【参考方案1】:

你不能按照你指定的方式去做。

声明您需要的任何类型的处理程序 - 同步、异步或可取消的异步。从 IMediator 方面来看,接口是仅异步的,专为现代主机设计。

但是,一种解决方法是创建一个 PersonRequestPersonRequestAsync 类,继承自 Person 类:

public class Person

    public int Id get; set;
    public string Name get; set;
    public int Age get; set;


//sync request
public class PersonRequest : Person, IRequest<Person>
 

//async request
public class PersonRequestAsync : Person, IRequest<Person>
 

然后,您的处理程序可能看起来像这样:

public class PersonHandler : IRequestHandler<PersonRequest, Person>

    public Task<Person> Handle(Person request, CancellationToken cancellationToken)
    
        request.ID = 1;
        request.Name = "Brian";
        request.Age = 53;
        return Task.FromResult(request);
    

您的async 处理程序如下:

public class PersonHandlerAsync : IRequestHandler<PersonRequestAsync, Person>

    public async Task<Person> Handle(PersonRequestAsync request, CancellationToken cancellationToken)
    
        request.ID = 1;
        request.Name = "Brian";
        request.Age = 53;

        //not sure what this is? Hopefully it's just here for demo purposes!
        var result = await Task.FromResult(request);

        await Task.Delay(30000);

        return result;
    

这有效地将PersonRequestAsyncPersonHandlerAsync 联系起来

【讨论】:

谢谢。在文档中有对 IAsyncRequestHandler 和 SendAsync 方法的引用。但是,我找不到它们。它们现在已经过时了吗? 是的,以前肯定有 - 我认为这在 v4 中已被删除 - 但看起来文档还没有完全更新

以上是关于有一个同步处理程序和一个异步处理程序的主要内容,如果未能解决你的问题,请参考以下文章

python异步(Async)编程

立即从同步代码执行异步回调

javascript中事件处理程序的异步或同步调用

C#异步编程

架构设计|异步请求如何同步处理?

java中异步处理和同步处理分别是啥意思