为什么在异步方法中通过错误执行



我正试图在winform的Web浏览器控件上实现一个宏链接事件。

以下是打开Web浏览器的按钮https://example.com/login.

private void button1_Click(object sender, EventArgs e)
{
SuppressCookiePersistence();
Form4 frm = new Form4(this);
Registry.SetValue(@"HKEY_CURRENT_USERSoftwareMicrosoftInternet ExplorerMainFeatureControlFEATURE_BROWSER_EMULATION",
AppDomain.CurrentDomain.FriendlyName, 11000);

if (SetValueForUsername != "" && SetValueForPassword != "")
{
frm.Show();
frm.webBrowser2.Navigate("https://example.com/login");
}
else
{
MessageBox.Show("error: Credentials missing");
}
}

下面的async void调用登录

void dologin()
{
webBrowser2.Document.GetElementById("username").SetAttribute("value", Form1.SetValueForUsername);
webBrowser2.Document.GetElementById("password").SetAttribute("value", Form1.SetValueForPassword);
HtmlElementCollection elc = this.webBrowser2.Document.GetElementsByTagName("button");
foreach (HtmlElement el in elc)
{
if (el.GetAttribute("type").Equals("submit"))
{
el.InvokeMember("Click");
}
}
}

下面的async void可以点击并加载索引为每页20个公民的页面

async Task CitizensPageLoadAsync()
{
await PageLoad(1);
HtmlElementCollection elc2 = this.webBrowser2.Document.GetElementsByTagName("input");
foreach (HtmlElement el2 in elc2)
{
if (el2.GetAttribute("value").Equals("CitizensLoad"))
{
el2.InvokeMember("Click");
}
}
}

在这一点上,我有一个大约500个结果的页面,每个页面20个结果。因此,为了找到包含公民的页面,我正在寻找我正在做的事情:

async Task selectcitizen()
{
await PageLoad(2);
bool Correct = false;
int page = 1;
do
{
page++;
HtmlElementCollection elc2 = this.webBrowser2.Document.GetElementsByTagName("a");
foreach (HtmlElement el2 in elc2)
{
if (el2.InnerText == citizenimlookingfor)
{
Correct = true;
MessageBox.Show("Found");
}
else
{
Correct = false;    webBrowser2.Navigate("https://example.com/displaycitizens.htm?d-16544-p=" + page + "");
}
}
} while (Correct != true);
}

此处使用的所有空隙

public void webBrowser2_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
dologin();
CitizensPageLoadAsync();
selectcitizen();
}

这是我的等待方法

private async Task PageLoad(int TimeOut)
{
TaskCompletionSource<bool> PageLoaded = null;
PageLoaded = new TaskCompletionSource<bool>();
int TimeElapsed = 0;
webBrowser2.DocumentCompleted += (s, e) =>
{
if (webBrowser2.ReadyState != WebBrowserReadyState.Complete) return;
if (PageLoaded.Task.IsCompleted) return; PageLoaded.SetResult(true);
};
//
while (PageLoaded.Task.Status != TaskStatus.RanToCompletion)
{
await Task.Delay(10);
TimeElapsed++;
if (TimeElapsed >= TimeOut * 100) PageLoaded.TrySetResult(true);
}
}

下面是我在selectcitizen((异常时得到的错误,我不知道为什么:

Managed Debugging Assistant 'DisconnectedContext' 
Message=Managed Debugging Assistant 'DisconnectedContext' : 'Transition into COM context 0xdea288 for this RuntimeCallableWrapper failed with the following error: System call failed. (Exception from HRESULT: 0x80010100 (RPC_E_SYS_CALL_FAILED)). This is typically because the COM context 0xdea288 where this RuntimeCallableWrapper was created has been disconnected or it is busy doing something else. Releasing the interfaces from the current COM context (COM context 0xdea340). This may cause corruption or data loss. To avoid this problem, please ensure that all COM contexts/apartments/threads stay alive and are available for context transition, until the application is completely done with the RuntimeCallableWrappers that represents COM components that live inside them.'

您可以将TaskCompletionSource放在类的作用域中。

在PageLoad(…(上启动它,并在引发webBrowser2.Completed时完成它。

这种方法不需要时间。如果你真的需要超时,你可以使用定时器。在类的范围内。

最新更新