简体   繁体   English

C#-调用Task.Result是否等到返回结果后再返回

[英]C# - Does calling Task.Result wait until result is returned before returning

Here is my code: 这是我的代码:

public void ConnectToWorldServer()
{
    if (socketReady)
    {
        return;
    }
    //Default host and port values;
    string host = ClientWorldServer.ServerIP;
    int port = ClientWorldServer.TCPPort;

    //ClientLoginServer ClientLoginServer = new ClientLoginServer();


    try
    {

        socket = new TcpClient(host, port);
        stream = socket.GetStream();
        socket.NoDelay = true;
        writer = new StreamWriter(stream);
        reader = new StreamReader(stream);
        socketReady = true;
        //Preserve the connection to worldserver thrue scenes
        UnityThread.executeInUpdate(() =>
        {
            DontDestroyOnLoad(worldserverConnection);
        });

        // Start listening for connections.
        while (true)
        {
            if (socketReady)
            {
                if (stream.DataAvailable)
                {
                    string sdata = reader.ReadLine();
                    if (sdata != null)
                    {

                        Task<JsonData> jsonConvert = Task<JsonData>.Factory.StartNew(() => convertJson(sdata));
                        UnityThread.executeInUpdate(() =>
                        {
                            OnIncomingData(jsonConvert.Result);
                        });
                    }
                }
            }
        }
    }
    catch (Exception e)
    {
        Debug.Log("Socket error : " + e.Message);
    }

}

private JsonData convertJson(string data)
{
    return JsonConvert.DeserializeObject<JsonData>(data);    
}

What I am wondering now is does this part of the code: 我现在想知道的是代码的这一部分:

UnityThread.executeInUpdate(() =>
{
    OnIncomingData(jsonConvert.Result);
});

block until this task returns back a result: 阻止,直到此任务返回结果:

Task<JsonData> jsonConvert = Task<JsonData>.Factory.StartNew(() => convertJson(sdata));

I am really not that familiar with Tasks. 我对任务真的不那么熟悉。 My goal is to run the json conversion and then execute OnIncomingData(jsonConvert.Result); 我的目标是运行json转换,然后执行OnIncomingData(jsonConvert.Result); .

I think my code is not doing that. 我认为我的代码没有这样做。 Why? 为什么?

When a thread invokes Task.Result it will block until the Task completes, either by returning a value, throwing an exception, or being canceled. 当线程调用Task.Result ,它将阻塞,直到任务完成为止,方法是返回值,引发异常或被取消。 From the documentation : 文档中

Accessing the property's get accessor blocks the calling thread until the asynchronous operation is complete; 访问属性的get访问器会阻塞调用线程,直到异步操作完成为止; it is equivalent to calling the Wait method. 它等效于调用Wait方法。

So, to be clear, calling Task<JsonData>.Factory.StartNew creates a Task (which represents some computation to be executed), and schedules it for execution (when it gets executed and on what thread is up to the default TaskScheduler , but StartNew should return immediately). 因此,要明确一点,调用Task<JsonData>.Factory.StartNew会创建一个Task (代表要执行的某些计算),并安排其执行时间(执行时间以及在哪个线程上运行的默认TaskScheduler ,但是StartNew应该立即返回)。 Your call to UnityThread.executeInUpdate will then happen without waiting for the Task you created to complete. 然后,无需等待您创建的Task完成就可以调用UnityThread.executeInUpdate At the point where UnityThread calls the anonymous function you passed to executeInUpdate that thread will block until the Task completes. UnityThread调用您传递给executeInUpdate的匿名函数时,该线程将阻塞,直到Task完成。 I'm not familiar with UnityThread.executeInUpdate so I cannot tell you whether it will block until that callback completes or not. 我对UnityThread.executeInUpdate不熟悉,所以我无法告诉您在回调完成之前是否会阻塞。

One thing to be aware of is that depending on how Unity works with threads, it is possible to create a deadlock by accessing the Result property. 要注意的一件事是,根据Unity与线程的工作方式,可以通过访问Result属性来创建死锁。 In some cases a Task will attempt to use a specific context to execute, and if you cause that context to block waiting for the Task to complete, it will never get a chance to run: https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html 在某些情况下,任务会尝试使用特定的上下文来执行,并且如果您导致该上下文被阻止以等待任务完成,则它将永远没有机会运行: https : //blog.stephencleary.com/2012 /07/dont-block-on-async-code.html

If you want to wait for the result then what is the point of using the Task . 如果要等待结果,那么使用Task什么意义? The right way of doing thing asynchronously is making your function async all the way. 异步执行操作的正确方法是使函数始终保持异步状态。

public async void ConnectToWorldServer()
{
   .....
   .....
// Here await will put this method call on a queue to finish later and will return from this method. 
         Task<JsonData> jsonConvert = await Task<JsonData>.Factory.StartNew(() => convertJson(sdata));
// After the task is finished, it will resume to this method here to execute next statement. 
         UnityThread.executeInUpdate(() =>
         {
            OnIncomingData(jsonConvert.Result);
         });
   .....
   .....
}

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

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