[英]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.