通用应用程序:无法在 `EnableTransferOwnership` 之后绑定 `StreamSocketListener`

Universal app: Cannot bind `StreamSocketListener` after `EnableTransferOwnership`

我正在关注 this sample 来实现后台服务器通用应用程序。下面是实验代码:

void MainPage::OnConnectionReceived(StreamSocketListener^ sender, StreamSocketListenerConnectionReceivedEventArgs^ args)
{
     OutputDebugString(L"Connection received\n");

     // No idea how to transfer request handling from foreground to background task!
}

void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
{
    // Code to register background task is omitted

    auto listener = ref new StreamSocketListener();
    listener->Control->QualityOfService = SocketQualityOfService::Normal;

    try
    {
        listener->EnableTransferOwnership(Task->TaskId, SocketActivityConnectedStandbyAction::Wake);
    }
    catch (...)
    {
        OutputDebugString(L"Error: cannot transfer ownership\n");
    }

    listener->ConnectionReceived += ref new TypedEventHandler<StreamSocketListener^, StreamSocketListenerConnectionReceivedEventArgs^>(this, &MainPage::OnConnectionReceived);

    create_task(listener->BindServiceNameAsync("56789", SocketProtectionLevel::PlainSocket))
        .then([this]()
    {
        OutputDebugString(L"Server started on port 56789\n");

        auto m_httpClient = ref new HttpClient();
        auto request = ref new HttpRequestMessage(HttpMethod::Get, ref new Uri("http://" + ip + ":56789/"));
        auto request_operation = m_httpClient->SendRequestAsync(request, HttpCompletionOption::ResponseContentRead);

        return create_task(request_operation);
    }).then([this](task<HttpResponseMessage^> previousTask)
    {
        try {
            auto response = previousTask.get();
            // Code to process the response is omitted as it is irrelevant to the question
        }
        catch (Exception^ ex)
        {
            OutputDebugString(("Error: " + ex->Message + "\n")->Data());
        }
    });
}

在 运行 时,我收到错误:所引用对象的类型不支持尝试的操作。 这表明 BindServiceNameAsync 失败我不知道为什么,因为在进行绑定之前我已经按照文档执行 EnableTransferOwnership 。我这里做错了什么?

您得到 引用的对象类型不支持尝试的操作。 因为您正在使用 SocketActivityConnectedStandbyAction::Wake。将其更改为 SocketActivityConnectedStandbyAction::DoNotWake.

以下伪代码应该让您了解还需要做什么才能使 StreamSocketListenerSocketActivityTrigger 一起工作:

// TODO: task = socketTaskBuilder.Register();

socketListener = new StreamSocketListener();

socketListener.ConnectionReceived += OnConnected;

await socketListener.BindServiceNameAsync(port);

socketListener.EnableTransferOwnership(
    task.TaskId,
    SocketActivityConnectedStandbyAction.DoNotWake);

// This is required, otherwise you may get error:
// A device attached to the system is not functioning.
// (Exception from HRESULT: 0x8007001F)
await socketListener.CancelIOAsync();

socketListener.TransferOwnership(socketId); 

然后,在后台任务中执行:

public async void Run(IBackgroundTaskInstance taskInstance)
{
    var deferral = taskInstance.GetDeferral();

    var details = taskInstance.TriggerDetails as
        SocketActivityTriggerDetails;

    var socketInformation = details.SocketInformation;
    var streamSocket = socketInformation.StreamSocket;
    var socketListener = socketInformation.StreamSocketListener;

    switch (details.Reason)
    {
        case SocketActivityTriggerReason.ConnectionAccepted:

            // TODO: read, write, etc.

            break;
        default:
            // ...

            break;
    }

    // ...

    deferral.Complete();
}