首页 > 解决方案 > 无法摆脱 C# 中的异步方法

问题描述

我有一个测试如下。下面的方法调用称为“ 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时,我想退出此方法。我会将响应存储在变量响应中,并在接下来的后续步骤中使用它。

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方法中出来。它只是停留在那里并超时说明空引用异常。在调试时,我得到了所需的响应。但由于执行没有进行,我无法进行下一步。

标签: c#asynchronous

解决方案


你必须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)
{
}

推荐阅读