我进行了如下测试。下面的方法调用名为“ ReceiveC2dAsync ”的异步方法。这将侦听“ SendEventAsync ”方法发送的消息。在发送消息之前,它开始监听。
public void CreatePlatformEventForDeviceCreatedWithoutObjectId()
{
var corId = Guid.NewGuid().ToString();
ScenarioContext.Current["CorrelationId"] = corId;
var iotHubUri = this.objStartupFixture.IoTHubHostName;
var deviceName = this.objStartupFixture.DevicePEName;
var iotHubConnxnString = this.objStartupFixture.IoTHubConnectionString;
this.ReceiveC2dAsync(iotHubUri, deviceName, iotHubConnxnString, 2);
var jsonContent = ScenarioContext.Current["InstanceObj"] as JObject;
Microsoft.Azure.Devices.Client.Message msg = this.CreateMessageForD2C(jsonContent, true);
msg.CorrelationId = corId;
this.deviceClient.SendEventAsync(msg);
Thread.Sleep(2000);
}
方法 ReceiveC2dAsync 如下所示。当满足条件 response.Count> = messageCount 时,我想退出此方法。我会将响应存储在变量 response 中,并在随后的后续步骤中使用它。
private async void ReceiveC2dAsync(string iotHubUri, string deviceName, string iotHubConnxnString, int messageCount)
{
var deviceId = this.GetDeviceID(iotHubConnxnString, deviceName);
this.deviceClient = DeviceClient.Create(iotHubUri, new DeviceAuthenticationWithRegistrySymmetricKey(deviceName, deviceId), Microsoft.Azure.Devices.Client.TransportType.Amqp_Tcp_Only);
var correlationId = ScenarioContext.Current["CorrelationId"] as string;
var dataRxd = false;
var flag = true;
ScenarioContext.Current["DataRxdStatus"] = dataRxd;
var response = new List<string>();
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while (flag)
{
try
{
if (stopwatch.ElapsedMilliseconds > 30000)
{
throw new Exception("Time elapsed waiting for C2D message");
}
Microsoft.Azure.Devices.Client.Message receivedMessage = await this.deviceClient.ReceiveAsync();
if (receivedMessage.CorrelationId.ToString() != correlationId)
{
if (stopwatch.ElapsedMilliseconds > 30000)
{
throw new Exception("Time elapsed waiting for C2D message");
}
continue;
}
var eventType = receivedMessage.Properties["eventType"];
response.Add(Encoding.ASCII.GetString(receivedMessage.GetBytes()));
ScenarioContext.Current["C2DResponse"] = response;
if (response.Count >= messageCount)
{
flag = false;
dataRxd = true;
ScenarioContext.Current["DataRxdStatus"] = dataRxd;
stopwatch.Stop();
break;
}
}
catch (ObjectDisposedException)
{
}
}
}
然后将执行下面的下一个方法
public void CheckDeviceInstanceAndRelatedConfigurationInstance()
{
\\This response I will receive from the above async method.
var c2dResponse = ScenarioContext.Current["C2DResponse"] as List<string>;
}
但是当前的问题是即使循环结束后,我的执行也没有从 ReceiveC2dAsync 方法中执行。它只是停留在那,并且超时,说明为Null Reference Exception。在调试时,我得到了所需的响应。但是由于执行没有进行,所以我无法继续执行下一步。
答案 0 :(得分:0)
您必须await
异步使用方法
public async Task CreatePlatformEventForDeviceCreatedWithoutObjectId()
{
//your code
await this.ReceiveC2dAsync(iotHubUri, deviceName, iotHubConnxnString, 2);
//your code
}
private async Task ReceiveC2dAsync(string iotHubUri, string deviceName, string iotHubConnxnString, int messageCount)
{
}
答案 1 :(得分:0)
异步/等待模式使用任务将代码转变为状态机。由于您不使用await关键字,因此此代码将“触发并忘记”。您的主线程将继续运行,忽略由Task Scheduler管理的async方法的Thread。
方法状态完成后,请使用await关键字继续执行线程。
使用await时,您还需要将方法签名也更改为异步。