调试库'异步方法调用及其返回值

etl2016

活跃成员
已加入
2016年6月29日
留言内容
39
编程经验
3-5
你好,

有没有一种方法可以正确调试异步接口?

我正在调用由StackExchange.Redis提供的异步库函数StringGetAsync。它以字符串数组作为输入,并反馈RedisValue []数组,该数组实际上是byte []类型。

下面的程序返回一个null数组,并知道原因-将3个断点放在一个等待行上,一个放在Sleep上,将一个放在return语句上,执行第一个断点后,程序以0作为退出退出状态(可能成功),不允许检查第二个和第三个断点。有一个Add-to-Watch设置,带有表达式arryOfValuesReceived [0] .ToString()来观察返回的数组的各个元素,但是,程序在第一个断点之后退出。

我是否可以知道此行为的可能原因,或者是否有任何手段捕获并查看返回的数组以进行进一步调试?谢谢你

C#:
private static async Task<RedisValue[]> GetMeValuesForMyKeys  (DataTable table)
{
var batch = new List<RedisKey> (100);

for (i = 0; i<table.Rows.Count; i++)
{
DataRow row = table.Rows[i];
batch.Add(row["keyColumn"].ToString () );
}

RedisValue[] arryOfValuesReceived = await db.StringGetAsync(batch.ToArray() );
Thread.Sleep(10000); // introduced to identify whether above or below statement is the rootcause, and it is noticed that above is the cause
return arryOfValuesReceived
}
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,531
地点
弗吉尼亚州切萨皮克
编程经验
10+
That's expected behavior. It' because your first breakpoint is hit right before you do the await on line 11. And what happens is that while the StringGetAsync() waiting for a response, the execution returns to the caller. If the caller terminates, then there is no returning back into the method to wait for the response to comeback.

也许值得回顾一下异步/等待的工作方式。曾经有一个更简洁的图表,但解释也更简洁。新的文字看起来更加详细:
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,531
地点
弗吉尼亚州切萨皮克
编程经验
10+
There are a couple of threads here from a user working with Manasys Jazz to make web services access to a COBOL style mainframes. One of the threads asks about how to make an async call synchronous so that he could also debug. The short answer is to not use async/await and synchronously wait for the .Result, but I can understand how this is not really debugging the async call, but rather just forcing it to be synchronous.
 

etl2016

活跃成员
已加入
2016年6月29日
留言内容
39
编程经验
3-5
谢谢您进行调试-我将ReadKey()放在调用方法中,并注意到控制流现象。这次,断点正确移动了。库方法StringGetAsync以异步方式提供其功能,因此,尽管我的要求是顺序的,但我需要相应地安排调用模块。 StringGet是Synchronous对应的API,但由于逐行处理,因此性能不佳。出于这个原因,我将使用StringGetAsync,因为它可以一次性将巨大的数组作为输入并非常快地获取相应的值。谢谢你。
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,531
地点
弗吉尼亚州切萨皮克
编程经验
10+
您的调用模块应类似于:
C#:
var values = await GetMeValuesForMyKeys(dataTable);
When the await returns, it should have the values populated.
 
最佳 底部