gpt4 book ai didi

c# - 如何在返回前等待回调

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:23:41 24 4
gpt4 key购买 nike

我正在尝试将代码从 .Net 移植到 Unity C#,但我坚持使用包含回调的语法。

基本上,我必须用 this one 替换 .Net 'HttpClient' 库,也称为“HttpClient”。但是“获取”语法不一样,它使用回调。我对 C# 和 Http 查询还很陌生,不知道如何处理这种语法以获得预期的返回。

用.Net写的原函数:

internal static JObject GetToBackOffice(string action)
{
var url = backOfficeUrl;
url = url + action;

HttpClient httpClient = new HttpClient();

var response =
httpClient.GetAsync(url
).Result;
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
var idProcess = Newtonsoft.Json.Linq.JObject.Parse(response.Content.ReadAsStringAsync().Result);

return idProcess;
}
else
return null;

我正在为 Unity 编写的 C# 代码:

internal class Utils
{
internal static JObject GetToBackOffice(string action)
{
var url = backOfficeUrl;
url = url + action;

HttpClient httpClient = new HttpClient();

JObject idProcess = new JObject();

httpClient.GetString(new Uri(url),
(response) =>
{
// Raised when the download completes
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
idProcess = Newtonsoft.Json.Linq.JObject.Parse(response.Data);
}
else
{
idProcess = null;
}
});
// Here I would like to wait for the response, so that idProcess is filled with the received data before returning
return idProcess;
}

public class Action
{
public bool SendData(string id, string secretKey, FakeData data)
{
var idProcess = Utils.GetToBackOffice(String.Format("Events/{0}/infos",id));
//...I do then something with idProcess
//Currently, when I use idProcess here, it is still empty since the GetString response hasn't been received yet when this line is executed

return true;
}
}

public class EventHubSimulator : MonoBehaviour
{
void Start()
{
//Fill the parameters (I skip the details)
string oId = ...;
string secretKey = ...;
var vh = ...;

Action action = new Action();
action.SendData(oId, secretKey, vh);
}
}

我的问题是,在 GetToBackOffice 函数之后,我的代码直接将“idProcess”用于其他用途,但该对象为空,因为尚未收到响应。我想在我的函数返回之前等待响应。

希望我说得足够清楚。我知道已经发布了类似的问题,但找不到针对我的具体问题的解决方案。


编辑:

最后我按照 Nain 的建议使用了协程,但无法按照他所说的方式得到我期望的结果。这种方法似乎可行(尽管这可能不是一个好方法)。

public class EventHubSimulator : MonoBehaviour
{
void Start()
{
//Fill the parameters (I skip the details)
string oId = ...;
string secretKey = ...;
var vh = ...;

Utils utils = new Utils();
StartCoroutine(utils.SendData(oId, secretKey, vh));
}
}

public class Utils: MonoBehaviour
{
private const string backOfficeUrl = "http://myurl/api/";

public CI.HttpClient.HttpResponseMessage<string> response;

public IEnumerator SendData(string id, string secretKey, FakeData data)
{
response = null;
yield return GetToBackOffice(String.Format("Events/{0}/infos", id)); //Make a Http Get request
//The next lines are executed once the response has been received
//Do something with response
Foo(response);
}

IEnumerator GetToBackOffice(string action)
{
var url = backOfficeUrl;
url = url + action;

//Make a Http Get request
HttpClient httpClient = new HttpClient();
httpClient.GetString(new Uri(url), (r) =>
{
// Raised when the download completes
if (r.StatusCode == System.Net.HttpStatusCode.OK)
{
//Once the response has been received, write it in the global variable
response = r;
Debug.Log("Response received : " + response);
}
else
{
Debug.Log("ERROR =============================================");
Debug.Log(r.ReasonPhrase);
throw new Exception(r.ReasonPhrase);
}
});

//Wait for the response to be received
yield return WaitForResponse();
Debug.Log("GetToBackOffice coroutine end ");
}

IEnumerator WaitForResponse()
{
Debug.Log("WaitForResponse Coroutine started");
//Wait for response to become be assigned
while (response == null)
{
yield return new WaitForSeconds(0.02f);
}
Debug.Log("WaitForResponse Coroutine ended");
}
}

最佳答案

一种解决方案是在 Nain 作为答案提交时轮询完成。如果您不想轮询,可以使用 TaskCompletionSourceThis Q&A更深入地探讨了原因和方式。

你的代码可以这样写:

async Task CallerMethod()
{
JObject result = await GetToBackOffice(...);
// Do something with result
}

internal static Task<JObject> GetToBackOffice(string action)
{
var tsc = new TaskCompletionSource<JObject>();
var url = backOfficeUrl;
url = url + action;

HttpClient httpClient = new HttpClient();

JObject idProcess = new JObject();

httpClient.GetString(new Uri(url),
(response) =>
{
// Raised when the download completes
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
tsc.SetResult(Newtonsoft.Json.Linq.JObject.Parse(response.Data));
}
else
{
tsc.SetResult(null);
}
});

return tsc.Task;
}

另请参阅 this异步方法调用协程并等待完成部分msdn 博文。

注意 任务和异步/等待支持仅在 beta functionality 时可用在团结中。另见 this发布。

关于c# - 如何在返回前等待回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48303985/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com