1

У меня есть приложение (WinForms). Он просто захватывает некоторые данные, делает некоторые работы над ним, а затем загружает результат в какое-то облачное хранилище. Теперь я использую сторонний код, который обрабатывает аутентификацию с облачным хранилищем для меня. Этот код создаст WinForm, в котором размещается элемент управления браузера, который появляется, если пользователь еще не предоставил учетные данные и не разрешил приложению использовать облачное хранилище. Прежде чем моя программа пойдет и сделает все, я хочу убедиться, что я уже аутентифицирован, поэтому в цикле Main() программы (Program.cs) я хочу использовать стороннюю библиотеку для аутентификации с облачным хранилищем и блокировать мой фактический код (// myCode), выполняемый до его завершения. «К сожалению» библиотека асинхронна, и я потратил большую часть сегодняшнего дня, пытаясь получить описанное мной поведение, - мой вопрос действительно «делает синхронную асинхронную функцию», но общие ответы, которые я видел вокруг кажется, не работают для меня.Использование асинхронных функций с UI синхронно

Так что у меня что-то вроде этого

static void Main(string[] args) 
{ 
OAuth.LoginAuthAsync("clientID", "client_secret", ...) 
//Don't want to get here until LoginAuthAsync is done 
application.run(myForm); //myCode 
} 

Но это будет всплывать веб-браузер и запустить свой код, который я хочу, чтобы произойти только после того, как в Интернете OAuth.LoginAuthAsync завершена.

Я не эксперт со всеми библиотеками TPL, но я провел время, играя с вещами, которые, как я считаю, должны работать, но не надо. Я пробовал:

Я попытался

 Task.Run(async() => 
      { 
       OAuth.LoginAuthAsync("123456", "asdasd", ...)); 
    ).Wait(); 

Который выдает ошибку в библиотеке третьей стороны

System.Threading.ThreadStateException: ActiveX контроль «8856f961-340a-11d0-a96b- 00c04fd705a2 'не может быть создан, потому что текущая нить не находится в однопоточной квартире. в System.Windows.Forms.WebBrowserBase..ctor (Строка clsidString) на System.Windows.Forms.WebBrowser..ctor()

Затем я попытался

 Thread tx = new Thread(() => OAuth.LoginAuthAsync("123456","asdasd", ……..)); 
     tx.SetApartmentState(ApartmentState.STA); 
     tx.Start(); 
     tx.Join(); 

, но это просто всплывает окно и оно немедленно исчезает, и // myCode выполняет.

У любого органа есть идеи, что я могу сделать здесь. Я попытался переместить метод внутри myForm _Load событие (это myForm, вызванное из application.run), но у меня такая же проблема.

Большое спасибо

P.S. Я не хочу использовать дополнительные сторонние библиотеки.

+0

Когда вы «заполняете» логин, можете ли вы поймать это событие и выбросить его, а затем вызвать соединение? Также, возможно, поместите это в начало приложения, прежде чем он вызовет application.run (yourForm) –

+0

Проверьте [это] (http://stackoverflow.com/q/20876645/1768303). – Noseratio

ответ

1

Вы можете заблокировать и дождаться завершения кода, используя метод Wait() на Task, возвращенный с OAuth.LoginAuthAsync. Это работает в консольном приложении, но может вызвать deadlock в приложении GUI/ASP.

static void Main(string[] args) 
{ 
    OAuth.LoginAuthAsync("clientID", "client_secret", ...).Wait(); 

    //Don't want to get here until LoginAuthAsync is done 
    application.run(myForm); //myCode 
} 

Для GUI приложений это лучше сделать соответствующий метод async, а затем await вызов OAuth.LoginAuthAsync однако Main не может быть async.При перемещении метода внутри метода myForm_Load вы должны быть в состоянии сделать await вызов:

public async void myForm_Load(object o, EventArgs e) 
{ 
    await OAuth.LoginAuthAsync("clientID", "client_secret", ...); 
} 

На мой взгляд, что является лучшим решением.

+0

Спасибо за ответ. К сожалению, первый метод приводит к блокировке GUI (просто пустая форма с курсором ожидания). Второй метод тоже не работает: выполнение продолжается как обычно, так как открывается окно входа в систему (а не поведение диалога, которое я за ним) – Prof

+0

Что можно сказать о появлении диалогового окна, а затем в обработчике события «Загрузить» для вызова этого диалогового окна 'OAuth.LoginAuthAsync'? –

Смежные вопросы