Я думаю, что следующий вспомогательный метод также может решить проблему.
private TResult InvokeAsyncFuncSynchronously<TResult>(Func< Task<TResult>> func)
{
TResult result = default(TResult);
var autoResetEvent = new AutoResetEvent(false);
Task.Run(async () =>
{
try
{
result = await func();
}
catch (Exception exc)
{
mErrorLogger.LogError(exc.ToString());
}
finally
{
autoResetEvent.Set();
}
});
autoResetEvent.WaitOne();
return result;
}
Может использоваться следующим образом:
InvokeAsyncFuncSynchronously(Service.GetCustomersAsync);
Есть несколько проблем с вашей лямбда-функцией.
Во-первых, fold
ожидает (a -> b -> b)
, так что технически, функцию с двумя аргументами. Прямо сейчас ваша лямбда принимает только 1 аргумент. Поскольку ваш fold
напоминает foldr
(сгибает справа), вторым аргументом должен быть объект накопитель , который собирает результат из каждого сгиба.
Во-вторых, вы работаете с кортежами, а не списками (как отметил pdexter в комментарии ). Таким образом, вы должны использовать функции fst
и snd
.
После некоторых модификаций лямбды:
\x acc -> (fst x:fst acc, snd x:snd acc)
Это добавит первый элемент из каждого кортежа к первому списку аккумулятора. И второй элемент из каждого кортежа во второй список аккумулятора. Некоторые результаты:
unzip' :: [(a,b)] -> ([a],[b])
unzip' = fold (\x acc -> (fst x:fst acc, snd x:snd acc)) ([],[])
unzip' [(1, 'a'), (2, 'b'), (3, 'c')]
([1,2,3],"abc")
После комментария Джона вы также можете воспользоваться преимуществами сопоставления с образцом в лямбде, заменив fst
и snd
. Это может увеличить строгость функции. Вы также можете заменить ([], [])
на mempty
, предопределенный пустой кортеж.
unzip' = fold (\(x, y) (xs, ys) -> (x:xs, y:ys)) mempty
Подсказка: Перед тем как перейти к функции unzip
, вы можете сначала изолировать и протестировать лямбду с помощью fold
.