Если раньше требовалось, что бы объект был наследником MarshalByRefObject, то для DispatchProxy нет этого ограничения.
Удобная штука
Если раньше я использовал DynamicObject .Net Core, AppDomain, WCF, RPC маршалинг по Tcp/Ip свой велосипед
То теперь можно использовать DispatchProxy
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Klikujiskaaan, Вы писали:
K>Здравствуйте, Serginio1, Вы писали:
S>>Удобная штука
K>Нет, год пишу тикеты, что бы сделали нормальную поддержку асинхронных вызовов, а воз и ныне там, пришлось запилить свой AsyncDispatchProxy.
А в чем проблема?
protected override object Invoke(MethodInfo targetMethod, object[] args)
{
try
{
// For this proxy implementation, we still want to call the original API
// (after logging has happened), so use reflection to invoke the desired
// API on our wrapped target object.var result = targetMethod.Invoke(Target, args) as Task;
var tcs = new TaskCompletionSource<object>();
CallAsyncMethod(result ,tcs);
result = tcs.Task;
return tcs.Task;
}
catch (TargetInvocationException exc)
{
// If the MethodInvoke.Invoke call fails, log a warning and then rethrow the exception
_logger.Warning(exc.InnerException, "Method {TypeName}.{MethodName} threw exception: {Exception}", targetMethod.DeclaringType.Name, targetMethod.Name, exc.InnerException);
throw exc.InnerException;
}
}
void CallAsyncMethod(Task task,TaskCompletionSource value)
{
try
{
var res= await task;
value.SetResult(resObj);
}
exeption{
{
value.TrySetException(new Exception(тра-ля-ля);
}
}
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Klikujiskaaan, Вы писали:
K>Здравствуйте, Serginio1, Вы писали:
S>>А в чем проблема?
K>Ну хотя бы в том, что в твоей реализации все выполнится синхронно.
Это как? Возвращается Task
var tcs = new TaskCompletionSource<object>();
CallAsyncMethod(result ,tcs);
return tcs.Task;
async Task CallAsyncMethod(Task task,TaskCompletionSource value)
{
try
{
var res= await task;
value.SetResult(resObj);
}
catch (TargetInvocationException exc)
{
value.TrySetException(exc.InnerException);
}
}
Ну и вызов
await proxy.CallAsyncMethod(); будет работать
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S>Здравствуйте, Klikujiskaaan, Вы писали:
K>>Здравствуйте, Serginio1, Вы писали:
S>>>А в чем проблема?
K>>Ну хотя бы в том, что в твоей реализации все выполнится синхронно.
S> Это как? Возвращается Task
Здравствуйте, Klikujiskaaan, Вы писали:
K>Здравствуйте, Serginio1, Вы писали:
S>>Здравствуйте, Klikujiskaaan, Вы писали:
K>>>Здравствуйте, Serginio1, Вы писали:
S>>>>А в чем проблема?
K>>>Ну хотя бы в том, что в твоей реализации все выполнится синхронно.
S>> Это как? Возвращается Task
K>А как ты внутри K>
Я же код написал. Просто вызвать без await. Это обычная практика с применением TaskCompletionSource
var tcs = new TaskCompletionSource<object>(); // Понятно, что не object а нужный тип
CallAsyncMethod(result ,tcs);
return tcs.Task;
Метод CallAsyncMethod вызовется без проблем. Просто на await вернет управление.
Но мы возвращаем tcs.Task которую и будет ожидать вызывающий код.
А результат уже вернем после получения
S>Метод CallAsyncMethod вызовется без проблем. Просто на await вернет управление. S>Но мы возвращаем tcs.Task которую и будет ожидать вызывающий код. S>А результат уже вернем после получения
А что бы постпроцессинг сделать в проксе нужно будет ContinueWith вызывать?
А если результат targetMethod.Invoke(_decorated, args) не Task, а Task<T>, нужно еще пару приседаний?
Зачем это все, если можно сделать
public abstract Task InvokeAsync(MethodInfo method, object[] args);
public abstract Task<T> InvokeAsyncT<T>(MethodInfo method, object[] args);
Здравствуйте, Klikujiskaaan, Вы писали:
K>Здравствуйте, Serginio1, Вы писали:
S>>Метод CallAsyncMethod вызовется без проблем. Просто на await вернет управление. S>>Но мы возвращаем tcs.Task которую и будет ожидать вызывающий код. S>>А результат уже вернем после получения
K>А что бы постпроцессинг сделать в проксе нужно будет ContinueWith вызывать? K>А если результат targetMethod.Invoke(_decorated, args) не Task, а Task<T>, нужно еще пару приседаний? K>Зачем это все, если можно сделать K>public abstract Task InvokeAsync(MethodInfo method, object[] args); K>public abstract Task<T> InvokeAsyncT<T>(MethodInfo method, object[] args);
Ну там всего то пара приседаний. Не проблема
Особо то и не вижу особого смысла, а сложностей больше. Нужно анализировать код с проверкой на async await
Может и сделают.
и солнце б утром не вставало, когда бы не было меня