Either<,> 上的匹配需要 Return 从 Async Lambda 键入 ValueTuple

Match on Either<,> Needs to Return Type Over ValueTuple from Async Lambda

我有一个验证步骤,用于检查 Kafka 消息是否针对预期事件正确形成。这个验证函数return是一个Either(左边是错误信息,右边是验证通过后的信息)。

下一步是在左侧或右侧进行匹配。如果是 Left,则为错误创建一个 EventTrace 对象。如果正确,使用异步方法从 Mongo 中的消息执行 ID 更新,然后从该异步调用的 Either<,> 创建一个 EventTrace 对象,该对象是 returned.

目前要从比赛中获取 EventTrace,我必须执行以下代码。

var errTrace = ErrorStringToErrorTrace.Apply(message).Apply(this.CurrentMessage);
var successTrace = SuccessStringToSuccessTrace.Apply(message).Apply(this.CurrentMessage);

var eventTracer = ValidateStatusEventMessage(message)
            .Match(
                (left) => errTrace(ValidationFailMessage(left.Message)),
                (right) => RouteUpdateMessageToEventTrace(UpdateUnid(message).Result, successTrace, errTrace)
            );

此代码的问题在于 .Result on UpdateUnid(message),这不是正确的异步。

如果我尝试使用 await 将异步应用于(右)lambda,return 匹配类型从 EventTrace 更改为 ValueTuple。

 var eventTracerTest = ValidateStatusEventMessage(message)
            .Match(
                (left) => errTrace(ValidationFailMessage(left.Message)),
                async (right) =>
                {
                    Either<CommonMessage, bool> update = await UpdateUnid(message);
                    RouteUpdateMessageToEventTrace(update, successTrace, errTrace);
                }
            );

我也尝试过映射来自 UpdateUnid 的任务 returned,但最终仍然出现异步警告并且需要使用 Result 并且最终还带有 Option>> return来自地图。

var mapTest = Some(message).Map(async (key) => await UpdateUnid(key));

如果能帮助解决这个异步难题,我们将不胜感激。

更新:将 repo link 添加到带有签名的示例中

Match on Either Async Sample

据我所见

async (right) => {
    Either<CommonMessage, bool> update = await UpdateUnid(message);
    RouteUpdateMessageToEventTrace(update, successTrace, errTrace);
});

不会 return Task<Right> 因为你在 lambda 中省略了 return:

async (right) => {
    Either<CommonMessage, bool> update = await UpdateUnid(message);
    return RouteUpdateMessageToEventTrace(update, successTrace, errTrace);
});

更新:您还需要离开 return 任务,如下所示:

var eventTracer = await ValidateStatusEventMessage(message)
.Match(
(left) => Task.FromResult(errTrace(ValidationFailMessage(left.Message))),
async (right) =>
{
    var updateUnidAsync = await UpdateUnidAsync(message);
    return RouteUpdateMessageToEventTrace(updateUnidAsync, successTrace,
        errTrace);
});

我必须与 LaYumba 功能包的维护者进行沟通。他的建议之一是让左 return 成为 Task.FromException,这让我的类型 return 成为任务,然后我等待它来获取事件跟踪对象。

        var eventTracerAsync = ValidateStatusEventMessage(message)
            .Match(
                async (left) => await Task.FromException<LotusNotesStatusEventTrace>(new Exception(ValidationFailMessage(left.Message))) ,
                async (right) => RouteUpdateMessageToEventTrace(await UpdateUnid(message), successTrace, errTrace)
            );


        var eventTracer = await eventTracerAsync;

他有另一个建议,建议使用 .Map() 而不是 .Match(),我将在一边尝试以供自己学习。