How do I get the return value of an activity running on a thread in C #?

I want to make a function to run stuff in the downstream ... aka keep executing stuff, without waiting for the function in line before issuing it.

So I made a little function here ...

public static object Do(System.Action Method)
{
      object ret;
      System.Threading.Thread t = new System.Threading.Thread(() => 
      {ret = Method(); });
      t.SetApartmentState(System.Threading.ApartmentState.STA);
      t.Start();
      return ret;
}

      

Looks simple ... there is only one problem ... I am getting the following errors

Cannot implicitly convert type 'void' to 'object'

Using an unassigned local variable 'ret'

I don't care about the second one because it will fix itself if I just fix the first ... but I didn't seem to find a solution for the first ...

In short: All I want is to get the return value of the selected function aka ...

I want the following code to work:

string TEST = Do(() => Console.ReadKey()).ToString();

      

But the method itself doesn't work.

+3


source to share


2 answers


Action

the delegate does not return a value.

Use Func<object>

to return object

from a passed function.

Also in this case, the variable will most likely be returned before the function completes.

I recommend using a combination instead async/await

. To make your construction work, you would do something like this:

public static async Task<object> Do(Func<object> Method)
{
    object ret = null;

    await Task.Run(
    () =>
    {
        ret = Method();
    });

    return ret;
} 

      

Which boils down to:



public static async Task<object> Do(Func<object> Method)
{
    return Task.Run(Method);
}  

      

Sample code:

class Program
{
    static AutoResetEvent MyThreadCompletedEvent = new AutoResetEvent(false);
    static async void MyThread()
    {
        Console.WriteLine((await MyClass<ConsoleKeyInfo>.Do(Console.ReadKey)).ToString());
        MyThreadCompletedEvent.Set();
    }

    static void Main(string[] args)
    {
        Task.Run(() => MyThread());

        // Do stuff

        // Ensure to wait for MyThread to complete
        MyThreadCompletedEvent.WaitOne();
    }
}

public static class MyClass<T>
{
    public static async Task<object> Do(Func<T> Method)
    {
        return await Task.Run(Method);
    }
}

      

Instead of creating a new thread, you can do:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(MyClass<ConsoleKeyInfo>.Do(Console.ReadKey));
    }
}

public static class MyClass<T>
{
    public static object Do(Func<T> Method)
    {
        return Method();
    }
}

      

+2


source


From the title:

How do I get the return value of an activity running on a thread in C #?

You can not. If the thread is still running, the "return value" has not yet been calculated. It is not available for refund even if you used the correct one Func<T>

instead Action<T>

.

In other words, the laws of physics of our universe, which we currently know about them, do not allow us to extract information from the future.



I want the following code to work:

string TEST = Do(() => Console.ReadKey()).ToString();

      

Assuming what you meant TEST

to have the value of the key pressed, you have to wait for the key to be pressed. The same could be obtained:

string TEST = Console.ReadKey().ToString();

      

(although you probably want to use a property .KeyChar

...)

+1


source







All Articles