EndInvoke()不返回(循环?死锁?)

时间:2017-01-31 21:22:05

标签: c# webbrowser-control invokerequired

我只是在玩Codeproject

这个简洁的代码

控件有一个安全的调用方法:

public static TResult SafeInvoke<T, TResult>(this T isi, Func<T, TResult> call) where T : ISynchronizeInvoke
{
   if (isi.InvokeRequired) { 
      IAsyncResult result = isi.BeginInvoke(call, new object[] { isi }); 
      object endResult = isi.EndInvoke(result); return (TResult)endResult; 
   }
   else
      return call(isi);
}

场景1:带有WebBrowser控件的Windows窗体应用程序。这个调用返回它应该返回的内容(返回的结果是暂时的,仅用于测试):

private void button1_Click(object sender, EventArgs e)
{
    Thread thread = new Thread(new ThreadStart(StartStuff));
    thread.Start();
}

private void StartStuff()
{        
    var document = webBrowser1.SafeInvoke(o => o.Document);    
}

到目前为止,创建这个安全调用片段的人的工作非常出色。

场景2:接下来我想运行一些处理一些基于WebBrowser的东西的单元测试。这个小小的测试将证明这一点:

[Test, Category("Thread Safety")]
public void TestIfThreadRaisesException()
{
    /* create STA thread where the browser will live and die in */
    Thread thread = new Thread(RunSTAContent);
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
    thread.Join();
}

private static void RunSTAContent()
{   /* simulate cross thread access to control */
    var stdBrowser = new System.Windows.Forms.WebBrowser();
    Task.Run(async () => await RunUnProblematicContent(stdBrowser)).Wait();
}

private static async Task RunUnProblematicContent(System.Windows.Forms.WebBrowser browser)
{
    await Task.Delay(1000);
    var doc = browser.SafeInvoke(o => o.Document);
    //...
}

这样,我得到了对SafeInvoke的无限调用,更确切地说,它在此结束:

object endResult = isi.EndInvoke(result);

你有一个暗示为什么调用永远不会结束?是不是因为我的自制STA线程?可能是与NUnit结合使用的控制台转轮问题吗?

1 个答案:

答案 0 :(得分:0)

正如Ivans评论所述,消息循环丢失了。 我遇到了这个我可以用于此目的的课程:)

MessageLoopApartment