简体   繁体   English

C#等待DLL异步方法完成

[英]C# wait DLL async method to finish

I have a DLL which has public Task<> method which returns return Task.Factory.StartNew(() => ...) . 我有一个具有public Task<>方法的DLL,该方法返回return Task.Factory.StartNew(() => ...) I am calling it within a program and I want the program to wait for the execution of the task to finish before it continues doing other things. 我正在程序中调用它,并且我希望程序在继续执行其他操作之前先等待任务执行完成。 I've added Thread.Sleep(6000) to the DLL to simulate longer execution. 我已将Thread.Sleep(6000)添加到DLL中以模拟更长的执行时间。

When I'm calling it like this 当我这样称呼它时

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

It just continues with execution (as expected). 它只是继续执行(如预期的那样)。 But then I tried this: 但是后来我尝试了这个:

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

And it doesn't work. 而且它不起作用。 How can I make it wait from outside of DLL? 如何让它从DLL外部等待?

Just Wait for the task that is being returned - don't spin up another Task just to call the original method: 只需Wait返回的任务-不要启动另一个 Task只是为了调用原始方法:

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

I think the calling method must have the async keyword in the definition: 我认为调用方法的定义中必须具有async关键字:

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

}

void or Task depends on which context you are in. 无效或任务取决于您所处的上下文。

When you wait() a Task.Factory.StartNew() the result is a Task Therefore you have to call wait() two times or you can use await operator. 当您wait() Task.Factory.StartNew() ,结果是一个Task因此,您必须调用两次wait()或使用await运算符。

Therefore you can do the following. 因此,您可以执行以下操作。

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

Or you can do the following 或者您可以执行以下操作

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

However from the question you have posted, it looks like your myMethod.Invoke() returns Task.Factor.StartNew() therefore I would like you to try 但是从您发布的问题来看,它看起来像myMethod.Invoke()返回Task.Factor.StartNew()因此我希望您尝试

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

However it is a bad practice to use Wait() and then Result() as it block the current thread. 但是,使用Wait()然后使用Result()是一个不好的做法,因为它会阻塞当前线程。 Therefore I would like you to use await. 因此,我希望您使用await。

This example may help: 该示例可能会有所帮助:

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 can cast your Invoke as a Task<> and then get the Result. 您可以将Invoke强制转换为Task <>,然后获取结果。 This will wait until the method is done executing. 这将等到该方法执行完毕。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM