C# 在COM仍在运行时访问在另一个线程中创建的COM包装器对象的属性

C# 在COM仍在运行时访问在另一个线程中创建的COM包装器对象的属性,c#,com,geckofx,C#,Com,Geckofx,嗨,我正在使用GeckoFX(FirefoxWebControl的COM包装器)。我正在创建浏览器,如下所示: public ScrapperGecko() // constructor { ThreadStart ts = new ThreadStart(CreateBrowser); CreateThread = new Thread(ts); CreateThread.SetApartmentState(ApartmentState.STA); Create

嗨,我正在使用GeckoFX(FirefoxWebControl的COM包装器)。我正在创建浏览器,如下所示:

public ScrapperGecko() // constructor
{
    ThreadStart ts = new ThreadStart(CreateBrowser);
    CreateThread = new Thread(ts);
    CreateThread.SetApartmentState(ApartmentState.STA);
    CreateThread.Start();
}

public void CreateBrowser()
{
    if (_Browser != null) return;
    Gecko.Xpcom.Initialize(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "xulrunner"));

    _Browser = new GeckoWebBrowser();

    _Browser.DocumentCompleted += _Browser_DocumentCompleted;
    frm.WindowState = FormWindowState.Maximized;
    _Browser.Height = frm.ClientSize.Height;
    _Browser.Width = frm.ClientSize.Width;
    _Browser.Left = 0;
    _Browser.Top = 0;
    _Browser.Dock = DockStyle.Fill;
    frm.ShowInTaskbar = true;
    frm.Controls.Add(_Browser);
    frm.Show();
}
public string GetCookie()
{
    if (_Browser == null || _Browser.Document == null || _Browser.Document.DocumentElement == null) //Throw exception
        return string.Empty;
    return _Browser.Document.Cookie;
}
但是,当我调用从另一个线程访问Gecko的Scrapersergecko方法时,如下所示:

public ScrapperGecko() // constructor
{
    ThreadStart ts = new ThreadStart(CreateBrowser);
    CreateThread = new Thread(ts);
    CreateThread.SetApartmentState(ApartmentState.STA);
    CreateThread.Start();
}

public void CreateBrowser()
{
    if (_Browser != null) return;
    Gecko.Xpcom.Initialize(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "xulrunner"));

    _Browser = new GeckoWebBrowser();

    _Browser.DocumentCompleted += _Browser_DocumentCompleted;
    frm.WindowState = FormWindowState.Maximized;
    _Browser.Height = frm.ClientSize.Height;
    _Browser.Width = frm.ClientSize.Width;
    _Browser.Left = 0;
    _Browser.Top = 0;
    _Browser.Dock = DockStyle.Fill;
    frm.ShowInTaskbar = true;
    frm.Controls.Add(_Browser);
    frm.Show();
}
public string GetCookie()
{
    if (_Browser == null || _Browser.Document == null || _Browser.Document.DocumentElement == null) //Throw exception
        return string.Empty;
    return _Browser.Document.Cookie;
}
每当它点击_Browser.Document时,就会抛出一个异常

类型的例外 中出现“System.Runtime.InteropServices.InvalidComObjectException” Geckofx-Winforms.dll,但未在用户代码中处理

附加信息:已从其 无法使用基础RCW

在那之后,我尝试修改方法,使其变成这样(使用invokeRequest),但之后它总是返回null,invokeRequest方法正确吗?为什么返回值为null,它假定包含cookie

public string GetCookie()
{
    WaitForBrowser();
    if (_Browser.InvokeRequired)
    {
        object obj = _Browser.Invoke(new Func<string>(GetCookie), null); // it works but the obj always **null** which it suppose to have value
        return (string)obj;
    }

    if (_Browser == null || _Browser.Document == null || _Browser.Document.DocumentElement == null)
        return string.Empty;
    return _Browser.Document.Cookie;
}
公共字符串GetCookie()
{
WaitForBrowser();
如果(_Browser.invokererequired)
{
object obj=_Browser.Invoke(new Func(GetCookie),null);//它可以工作,但obj总是**null**它认为它有值
返回(字符串)对象;
}
如果(_Browser==null | | | u Browser.Document==null | | | u Browser.Document.DocumentElement==null)
返回字符串。空;
返回_Browser.Document.Cookie;
}

COM仍在运行,尚未发布,因为我将COM对象设置为静态,并且从未单独调用Dispose,我可以确定COM仍在运行,因此它不应与有关COM发布和RCW错误的其他问题相关。

您好,它可能与该问题无关,因为这个问题是关于COM被释放的,但是我的问题是COM仍然在运行,它还没有关闭。所以,当通过
\u Browser.Invoke调用
GetCookie
时,
if
语句中的哪个属性导致它返回
string.Empty
?嗨,Alex,它返回null而不是string.Empty。但是cookie在调用之前就已经设置好了,它应该有valueDoes
WaitForBrowser()
也需要被封送到包含
\u Browser
实例的STA线程,也就是说,移动到
if(\u Browser.InvokeRequired)
块的下面?您的代码存在线程争用错误,编写线程化代码时的一个基本错误。你的第二个版本稍微好一点,但仍然不够好。浏览器的就绪信号并不意味着cookie有效。必须以正确的方式执行此操作,使用DocumentCompleted事件,获取cookie,然后启动线程。那样就没有比赛的危险。