Доступ к окну потока пользовательского интерфейса из другого потока и класса для окна AAD - PullRequest
0 голосов
/ 17 февраля 2020

Я создаю WPF, который предлагает пользователю войти в систему Azure AD, и я не могу ответить на звонок, вместо этого он зависает в потоке пользовательского интерфейса. Вот код, который я пытаюсь вызвать

 authResult = _application.AcquireTokenInteractive(_scopes)
                          .WithParentActivityOrWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle)
                          .ExecuteAsync().Result;

Я попытался обернуть это в вызов диспетчера, например,

internal static Dispatcher GetDispatcher(this DispatcherObject source)
{
    //use the application's dispatcher by default
    if (Application.Current != null) return Application.Current.Dispatcher;

    //fallback for WinForms environments
    if (source.Dispatcher != null) return source.Dispatcher;

    // ultimately use the thread's dispatcher
    return Dispatcher.CurrentDispatcher;
}

var dispatcher = MainWindow.main.GetDispatcher();

if (!dispatcher.CheckAccess())
{
    var action = new Action(() => {
        authResult = _application.AcquireTokenInteractive(_scopes)
                     .WithParentActivityOrWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle)
                     .ExecuteAsync().Result;
        });
        dispatcher.Invoke(DispatcherPriority.Normal, action);
        return;
}

Если я переместил интерактивный вызов в моем MainWindow. xaml.cs, он работает нормально, но я хочу переместить его в класс обслуживания, чтобы очистить вещи. Что я могу делать не так? Приведенный выше код находится в функции с такой подписью

 public async Task AuthenticateRequestAsync(HttpRequestMessage request)

. При необходимости я могу предоставить дополнительную информацию.

Ответы [ 2 ]

3 голосов
/ 17 февраля 2020
_application.AcquireTokenInteractive(_scopes)
                          .WithParentActivityOrWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle)
                          .ExecuteAsync().Result; 

Результат вызова блокирует поток пользовательского интерфейса. Вместо этого вам нужно дождаться звонка.

await _application.AcquireTokenInteractive(_scopes)
                          .WithParentActivityOrWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle)
                          .ExecuteAsync();

Вам необходимо также отметить функцию async.

0 голосов
/ 17 февраля 2020

Проверьте решение juunas. Также, если вы решили поместить этот код в библиотеку, рассмотрите возможность использования .ConfigureAwait (false), чтобы избежать нежелательного сценария. Эта ссылка говорит об этом с некоторыми примерами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...