Migrating RealProxy Usage to DispatchProxy
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 13.01.21 08:49
Оценка:
Migrating RealProxy Usage to DispatchProxy

Если раньше требовалось, что бы объект был наследником MarshalByRefObject, то для DispatchProxy нет этого ограничения.
Удобная штука
Если раньше я использовал DynamicObject .Net Core, AppDomain, WCF, RPC маршалинг по Tcp/Ip свой велосипед
То теперь можно использовать DispatchProxy
и солнце б утром не вставало, когда бы не было меня
Отредактировано 13.01.2021 8:53 Serginio1 . Предыдущая версия .
Re: Migrating RealProxy Usage to DispatchProxy
От: Klikujiskaaan КНДР  
Дата: 13.01.21 09:48
Оценка: +1
Здравствуйте, Serginio1, Вы писали:

S>Удобная штука


Нет, год пишу тикеты, что бы сделали нормальную поддержку асинхронных вызовов, а воз и ныне там, пришлось запилить свой AsyncDispatchProxy.
Re[2]: Migrating RealProxy Usage to DispatchProxy
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 13.01.21 11:06
Оценка:
Здравствуйте, 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(тра-ля-ля);
}

}
и солнце б утром не вставало, когда бы не было меня
Re[3]: Migrating RealProxy Usage to DispatchProxy
От: Klikujiskaaan КНДР  
Дата: 13.01.21 11:22
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>А в чем проблема?


Ну хотя бы в том, что в твоей реализации все выполнится синхронно.
Re[4]: Migrating RealProxy Usage to DispatchProxy
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 13.01.21 11:44
Оценка:
Здравствуйте, 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(); будет работать
и солнце б утром не вставало, когда бы не было меня
Re[5]: Migrating RealProxy Usage to DispatchProxy
От: Klikujiskaaan КНДР  
Дата: 13.01.21 12:00
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Здравствуйте, Klikujiskaaan, Вы писали:


K>>Здравствуйте, Serginio1, Вы писали:


S>>>А в чем проблема?


K>>Ну хотя бы в том, что в твоей реализации все выполнится синхронно.


S> Это как? Возвращается Task


А как ты внутри
 protected override object Invoke(MethodInfo targetMethod, object[] args)

Собрался вызывать
async Task CallAsyncMethod(Task task,TaskCompletionSource value)

?
Re[6]: Migrating RealProxy Usage to DispatchProxy
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 13.01.21 12:21
Оценка:
Здравствуйте, Klikujiskaaan, Вы писали:

K>Здравствуйте, Serginio1, Вы писали:


S>>Здравствуйте, Klikujiskaaan, Вы писали:


K>>>Здравствуйте, Serginio1, Вы писали:


S>>>>А в чем проблема?


K>>>Ну хотя бы в том, что в твоей реализации все выполнится синхронно.


S>> Это как? Возвращается Task


K>А как ты внутри

K>
K> protected override object Invoke(MethodInfo targetMethod, object[] args)
K>

K> Собрался вызывать
K>
K>async Task CallAsyncMethod(Task task,TaskCompletionSource value)
K>

K>?

Я же код написал. Просто вызвать без await. Это обычная практика с применением TaskCompletionSource

var tcs = new TaskCompletionSource<object>(); // Понятно, что не object а нужный тип
CallAsyncMethod(result ,tcs);
return tcs.Task;


Метод CallAsyncMethod вызовется без проблем. Просто на await вернет управление.
Но мы возвращаем tcs.Task которую и будет ожидать вызывающий код.
А результат уже вернем после получения

async Task CallAsyncMethod(Task task,TaskCompletionSource value)
{
try
{
  var res= await task;
  value.SetResult(resObj);
                   
}
catch (TargetInvocationException exc)
        {
             
              value.TrySetException(exc.InnerException);
        }

}


У меня так для удаленных вызовов сделано через DinamicObject.
https://habr.com/ru/post/323096/
Для вызова асинхронного метода:


// public async Task<V> GenericMethodAsync<K, V>(K param, string param4 = "Test")
var GenericArgs = new object[] { "System.Int32", "System.String" };
object resTask = await TO.async.GenericMethodAsync(GenericArgs , 44);

Нужно перед именем асинхронного метода добавить слово async

Если у вас есть Task, то можно дождаться выполнения, вызвав:

int res =await wrap.async.ReturnParam(task);

async мне нужен, что бы знать, что метод возвращает Task
и солнце б утром не вставало, когда бы не было меня
Re[7]: Migrating RealProxy Usage to DispatchProxy
От: Klikujiskaaan КНДР  
Дата: 13.01.21 12:30
Оценка:
Здравствуйте, Serginio1, Вы писали:


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);
Re[8]: Migrating RealProxy Usage to DispatchProxy
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 13.01.21 12:55
Оценка:
Здравствуйте, 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
Может и сделают.
и солнце б утром не вставало, когда бы не было меня
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.