【发布时间】:2021-04-15 01:15:33
【问题描述】:
有人可以看看这段代码并告诉我我做错了什么。在我看来,这 3 种方法应该以相同的方式运行,但它们一个接一个地运行。请看写在控制台上的时间。在我看来,所有 Console.WriteLine 都应该显示 ~60ms。 下面的代码示例:
private async void GetOneCombination(string firstMarket, string secondMarket, string thirdMarket, decimal amountOfFirstCurrency)
{
Stopwatch sw = new Stopwatch();
sw.Start();
Task<GetMarketResponse> result = _accessMethods.GetOrderbook(firstMarket);
Console.WriteLine(sw.ElapsedMilliseconds); // ~60ms
Task<GetMarketResponse> result1 = _accessMethods.GetOrderbook(secondMarket);
Console.WriteLine(sw.ElapsedMilliseconds); // ~130 ms
Task<GetMarketResponse> result2 = _accessMethods.GetOrderbook(thirdMarket);
Console.WriteLine(sw.ElapsedMilliseconds); // ~200 ms
var getMarketResponses = await Task.WhenAll(result, result1, result2);
}
编辑: 老实说,我认为这个方法里面是什么并不重要,我认为无论里面做什么,它都会同时完成3次
public async Task<GetMarketResponse> GetOrderbook(string market = "USD")
{
var address = AddressBook._orderbook + market;
var response = MethodExecutionTimeMeasurer.Invoke(() =>
_client.ExecuteGetAsyncPublic<GetMarketResponse>(address), out timespan);
_logger.LogInformation(string.Format("OrderBook requested for [{0}], response message: {1}. Time[ms]:{2}",
address,
response.Status,
timespan));
return response;
}
和 ExecuteGetAsyncPublic:
public async Task<T> ExecuteGetAsyncPublic<T>(string method)
where T : IBasicResponse
{
var response = await _httpClient.GetAsync(method).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
var responseData = JsonConvert.DeserializeObject<T>(json);
return responseData;
}
方法执行时间测量器
public static class MethodExecutionTimeMeasurer
{
public static T Invoke<T>(Func<Task<T>> action, out TimeSpan timeSpan)
{
var timer = Stopwatch.StartNew();
var res = action.Invoke();
res.Wait();
timer.Stop();
timeSpan = timer.Elapsed;
return res.Result;
}
public static void Invoke(Action action, out TimeSpan timeSpan)
{
var timer = Stopwatch.StartNew();
action.Invoke();
timer.Stop();
timeSpan = timer.Elapsed;
}
}
【问题讨论】:
-
如果你
var resultX = await _accessMethods.GetOrderbook()3 次,它会显示什么?也显示GetOrderbook的代码 -
作为旁注,avoid async void。请改用
async Task。关于您的主要问题,您能否对其进行编辑并包含GetOrderbook方法? -
除了@Theodor Zoulias 的注释(这里最好返回一个 Task 而不是 void ),我同意,在这种情况下,我猜方法的实现是问题所在(但如果没有看到就很难看到实施)。你可以很容易地弄清楚这一点,将每个呼叫包装在
Task.Run(() => _access.methods.Getorderbook(...));中(仅用于测试) -
感谢回复,我编辑了帖子。
-
是的,我在你写这篇文章的时候添加了它。我有这个 res.Stop() 似乎是问题所在。但是你能解释一下为什么吗?我是异步方法的新手。
标签: c# .net multithreading asynchronous task