2016-10-26 6 views
0

У меня есть DLL, которая имеет public Task<> метод, который возвращает return Task.Factory.StartNew(() => ...). Я называю это в рамках программы, и я хочу, чтобы программа дождалась завершения выполнения задачи, прежде чем она продолжит делать другие вещи. Я добавил Thread.Sleep(6000) в DLL, чтобы имитировать более длительное выполнение.C# wait DLL async метод для завершения

Когда я звоню его как этот

var invokedTask = myMethod.Invoke(Activator.CreateInstance(myClass), myParams); 

Он просто продолжает с исполнением (как и ожидалось). Но затем я попробовал это:

var invokedTask = Task.Factory.StartNew(() => myMethod.Invoke(Activator.CreateInstance(myClass), myParams)); 
invokedTask.Wait(); 

И это не работает. Как я могу заставить его ждать из-за пределов DLL?

+0

Во втором примере вы создаете * новую * 'Задачу'. Единственное задание, которое вы даете этой задаче, - запустить функцию 'myMethod' и * игнорировать * задачу, которую она возвращает. Поэтому, конечно, что «Задача» не займет много времени. Почему вы не просто 'Wait'' invokedTask' в первом примере? –

+0

Пробовал это уже, но 'invokedTask' не типа' Task', а 'object' – Norgul

+1

Но это действительно' Задача'. Все, что вам нужно, это бросить - не сбивать с толку создание большего количества 'Task'. –

ответ

1

Просто Wait для выполнения этой задачи, которая возвращается - не раскручивается другойTask просто назвать оригинальный метод:

var invokedTask = (Task)myMethod.Invoke(Activator.CreateInstance(myClass), myParams); 
invokedTask.Wait(); 
0

Я думаю, что вызывающий метод должен иметь асинхронное ключевое слово в определении:.

async void (or Task) MyCaller() 
{ 
    await Task.Factory.StartNew(() => myMethod.Invoke(Activator.CreateInstance(myClass), myParams)); 

} 

пустоту или задача зависит от того, какого контекста вы в

0

Когда вы wait()Task.Factory.StartNew() результата являются Task Для того, чтобы позвонить в систему: wait(), вы можете позвонить по телефону await.

Поэтому вы можете сделать следующее.

var invokedTask = Task.Factory.StartNew(() => myMethod.Invoke(Activator.CreateInstance(myClass), myParams)); 
var result=await await invokedTask; 

Или вы можете сделать следующее

var invokedTask = Task.Factory.StartNew(() => myMethod.Invoke(Activator.CreateInstance(myClass), myParams)); 
invokedTask.Wait(); 
var resultTask=invokedTask.Result; 
resultTask.Wait(); 
var result=resultTask.Result; 

Однако от вопроса вы в курсе, это выглядит как ваш myMethod.Invoke() возвращается Task.Factor.StartNew() поэтому я хотел бы, чтобы попробовать

var result =await await myMethod.Invoke(Activator.CreateInstance(myClass), myParams); 

Однако это неправильная практика использования Wait(), а затем Result(), поскольку она блокирует текущий поток. Поэтому я хотел бы, чтобы вы использовали ожидание.

0

Этот пример может помочь:

public class MagicClass 
{ 
    private int magicBaseValue; 

    public MagicClass() 
    { 
     magicBaseValue = 9; 
    } 

    public Task<int> ItsMagic(int preMagic) 
    { 
     return Task.Factory.StartNew(() => preMagic * magicBaseValue); 
    } 
} 

public class TestMethodInfo 
{ 
    public static void Main() 
    { 
     // Get the ItsMagic method and invoke with a parameter value of 100 
     Type magicType = typeof(MagicClass); 
     MethodInfo magicMethod = magicType.GetMethod("ItsMagic"); 
     var magicValue = ((Task<int>)(magicMethod.Invoke(Activator.CreateInstance(typeof(MagicClass)), new object[] { 100 }))).Result; 

     Console.WriteLine("MethodInfo.Invoke() Example\n"); 
     Console.WriteLine("MagicClass.ItsMagic() returned: {0}", magicValue.ToString()); 

     Console.ReadKey(); 
    } 
} 

You может вызывать Invoke как задачу <>, а затем получить результат. Это будет ждать выполнения метода.

Смежные вопросы