[英]C# - Does calling Task.Result wait until result is returned before returning
这是我的代码:
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);
}
我现在想知道的是代码的这一部分:
UnityThread.executeInUpdate(() =>
{
OnIncomingData(jsonConvert.Result);
});
阻止,直到此任务返回结果:
Task<JsonData> jsonConvert = Task<JsonData>.Factory.StartNew(() => convertJson(sdata));
我对任务真的不那么熟悉。 我的目标是运行json转换,然后执行OnIncomingData(jsonConvert.Result);
。
我认为我的代码没有这样做。 为什么?
当线程调用Task.Result
,它将阻塞,直到任务完成为止,方法是返回值,引发异常或被取消。 从文档中 :
访问属性的get访问器会阻塞调用线程,直到异步操作完成为止; 它等效于调用Wait方法。
因此,要明确一点,调用Task<JsonData>.Factory.StartNew
会创建一个Task
(代表要执行的某些计算),并安排其执行时间(执行时间以及在哪个线程上运行的默认TaskScheduler
,但是StartNew
应该立即返回)。 然后,无需等待您创建的Task
完成就可以调用UnityThread.executeInUpdate
。 在UnityThread
调用您传递给executeInUpdate
的匿名函数时,该线程将阻塞,直到Task
完成。 我对UnityThread.executeInUpdate
不熟悉,所以我无法告诉您在回调完成之前是否会阻塞。
要注意的一件事是,根据Unity与线程的工作方式,可以通过访问Result
属性来创建死锁。 在某些情况下,任务会尝试使用特定的上下文来执行,并且如果您导致该上下文被阻止以等待任务完成,则它将永远没有机会运行: https : //blog.stephencleary.com/2012 /07/dont-block-on-async-code.html
如果要等待结果,那么使用Task
什么意义? 异步执行操作的正确方法是使函数始终保持异步状态。
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.