Pergunta

When I have the following code, it executes async:

Task.Factory.StartNew(() => new Class(string, string2, string3));

When I make a generic method out of it like this, async doesn´t work anymore:

private void StartTask<T>(string, string2, string3) where T : BaseClass10
{
    var instance = (T) Activator.CreateInstance(typeof (T), string, string2, string3);
    Task.Factory.StartNew(() => instance);
}

I execute it like this:

StartNew<SomeClass>(string1, string2, string);
StartNew<SomeClass2>(string1, string2, string);

The second StartNew gets executed after the first finishes...what could be the reason?

Edit: SomeClass code:

public class SomeClass {
public SomeClass(string1, string2, string3){
// Long running process that takes time to complete. For example Thread.Sleep or what ever.
 }  
}
Foi útil?

Solução 2

Your original StartTask method:

private void StartTask<T>(string, string2, string3) where T : BaseClass10
{
    var instance = (T) Activator.CreateInstance(typeof (T), string, string2, string3);
    Task.Factory.StartNew(() => instance);
}

If the long running process happens in the constructor of T, then notice that the long running process happens outside of Task.Factory.StartNew().

Move the long running process into a method (e.g LongRunningProcess()) on T, then you can do this:

private void StartTask<T>(string, string2, string3) where T : BaseClass10
{
    var instance = (T) Activator.CreateInstance(typeof (T), string, string2, string3);
    Task.Factory.StartNew(() => instance.LongRunningProcess());
}

I don't think it's a good idea to have the long running process happening in a constructor.

Outras dicas

I see what you mean. Your first version calls the constructor in Task (probably threadpool thread). So it will return immediately before completion. where as in your second method you call Activator.CreateInstance which is what actually creating the instance and executing the constructor.

As you can see Activator.CreateInstance is called from calling thread itself rather than inside the task, it executes synchronously.

To make the generic method as you expect you need to wrap it in Task like this:

private void StartTask<T>(string, string2, string3) where T : BaseClass10
{
    Task.Factory.StartNew(() => (T) Activator.CreateInstance(typeof (T), string, string2, string3));
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top