I can not cancel "IAsyncOperation<DevicePairingResult> pairingOperation = customPairing.PairAsync()"

LI LIU 31 Reputation points
2022-05-06T02:35:05.793+00:00

I use DeviceInformationCustomPairing API to pair a wifi direct device. My code is as follows:
bool WifiDirectClient::RequestPairDeviceAsync(DeviceInformationPairing pairing)
{
WiFiDirectConnectionParameters connctionParameter;
connctionParameter.GroupOwnerIntent(0);
DevicePairingKinds devicePairingKinds = DevicePairingKinds::None;
connctionParameter.PreferenceOrderedConfigurationMethods().Append(WiFiDirectConfigurationMethod::PushButton);
devicePairingKinds |=
WiFiDirectConnectionParameters::GetDevicePairingKinds(WiFiDirectConfigurationMethod::PushButton);
connctionParameter.PreferredPairingProcedure(WiFiDirectPairingProcedure::GroupOwnerNegotiation);
DeviceInformationCustomPairing customPairing = pairing.Custom();
event_token token = customPairing.PairingRequested({ this, &WifiDirectClient::PairingRequestedHandler });
IAsyncOperation<DevicePairingResult> pairingOperation = customPairing.PairAsync(devicePairingKinds,
DevicePairingProtectionLevel::Default, connctionParameter);
AsyncStatus pairStatus = pairingOperation.wait_for(TimeSpan(PAIR_TIMEOUT)); // PAIR_TIMEOUT is 30s
qDebug() << "after get PairAsync";
if (pairStatus != AsyncStatus::Completed) {
if (pairStatus == AsyncStatus::Started) {
qDebug() << "PairAsync fail errorcode : " << pairingOperation.ErrorCode() << "operation status : " << static_cast<int>(pairStatus);
pairingOperation.Cancel();
} else {
qDebug() << "PairAsync fail errorcode : " << pairingOperation.ErrorCode() << "operation status : " << static_cast<int>(pairStatus);
}
return false;
}
DevicePairingResult result = pairingOperation.GetResults();
if (result == nullptr) {
qDebug() << "result is null";
return false;
}
if (result.Status() != DevicePairingResultStatus::Paired
&& result.Status() != DevicePairingResultStatus::AlreadyPaired) {
qDebug() << "PairAsync failed status : " << static_cast<int>(result.Status());
return false;
}
qDebug() << "PairAsync success";
return true;
}

When I select a device and push connect button, I can see the confirmation dialog popping up on the peer device screen. I don not click accept button. And then I wait for 30 seconds. The function wait_for times out. I can get output : "PairAsync fail errorcode : 0 operation status : 0". If I connect the device agin, the application will crash. If I close my application and connect any wifi direct device, the PairAsync operation fails all the time. This process lasts about a minute and a half. When it timed out, I had called the cancel method, but I felt that the underlying task was not canceled.

I also test get() method rather than wait_for() method. The code is as follows:
DevicePairingResult result = pairingOperation.get();

When I select a device and push connect button, I can see the confirmation dialog popping up on the peer device screen. I don not click accept button. The PairAsync blocks about a minute and a half.

I also tried FromIdAsync function, it behaves the same way.
https://learn.microsoft.com/en-us/answers/questions/802011/i-can-not-cancel-34iasyncoperationltwifidirectdevi.html

I also tried to test the official Microsoft demo: "Windows-universal-samples-main\Samples\WiFiDirect" and "Windows-universal-samples-main\Samples\DeviceEnumerationAndPairing" in cpp/winrt and c#. These two demos behave the same way as my own application.

I also tried the connection feature that comes with windows. I was surprised to find that this connection feature has the ability to cancel at will and re-initiate a connection at will. I'm not sure if this feature also calls the PairAsync interface, but it does have the ability to unpair at any time.

I want to know how to cancel PairAsync thoroughly.

Universal Windows Platform (UWP)
{count} votes

Accepted answer
  1. Roy Li - MSFT 32,051 Reputation points Microsoft Vendor
    2022-05-19T01:37:06.36+00:00

    Hello,

    Welcome to Microsoft Q&A!

    I've consulted the team about this. It has been confirmed that the DeviceInformationCustomPairing.PairAsync() and WiFiDirectDevice.FromIdAsync() can't be canceled. This behavior has nothing to do with your cancelation operation. You just have to wait for the first pair operation to fail before you can try again.

    The team also suggests that you could submit a feature request about this in the Feedback Hub. You could find the Feedback Hub in the Start Menu. Please select Developer Platform->API Feedback as the category when you submit your request. The related team will check the request.

    Thank you.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. LI LIU 31 Reputation points
    2022-05-06T02:35:58.693+00:00
    bool WifiDirectClient::RequestPairDeviceAsync(DeviceInformationPairing pairing)
    {
    WiFiDirectConnectionParameters connctionParameter;
    connctionParameter.GroupOwnerIntent(0);
    DevicePairingKinds devicePairingKinds = DevicePairingKinds::None;
    connctionParameter.PreferenceOrderedConfigurationMethods().Append(WiFiDirectConfigurationMethod::PushButton);
    devicePairingKinds |=
    WiFiDirectConnectionParameters::GetDevicePairingKinds(WiFiDirectConfigurationMethod::PushButton);
    connctionParameter.PreferredPairingProcedure(WiFiDirectPairingProcedure::GroupOwnerNegotiation);
    DeviceInformationCustomPairing customPairing = pairing.Custom();
    event_token token = customPairing.PairingRequested({ this, &WifiDirectClient::PairingRequestedHandler });
    IAsyncOperation<DevicePairingResult> pairingOperation = customPairing.PairAsync(devicePairingKinds,
    DevicePairingProtectionLevel::Default, connctionParameter);
    AsyncStatus pairStatus = pairingOperation.wait_for(TimeSpan(PAIR_TIMEOUT)); // PAIR_TIMEOUT is 30s
    qDebug() << "after get PairAsync";
    if (pairStatus != AsyncStatus::Completed) {
    if (pairStatus == AsyncStatus::Started) {
    qDebug() << "PairAsync fail errorcode : " << pairingOperation.ErrorCode() << "operation status : " << static_cast<int>(pairStatus);
    pairingOperation.Cancel();
    } else {
    qDebug() << "PairAsync fail errorcode : " << pairingOperation.ErrorCode() << "operation status : " << static_cast<int>(pairStatus);
    }
    return false;
    }
    DevicePairingResult result = pairingOperation.GetResults();
    if (result == nullptr) {
    qDebug() << "result is null";
    return false;
    }
    if (result.Status() != DevicePairingResultStatus::Paired
    && result.Status() != DevicePairingResultStatus::AlreadyPaired) {
    qDebug() << "PairAsync failed status : " << static_cast<int>(result.Status());
    return false;
    }
    qDebug() << "PairAsync success";
    return true;
    }