我正在使用来自后台线程的STA COM对象,其中一个COM对象的方法将阻塞,当我从处于STA线程模式的新线程调用它时,因为COM对象的模式是STA,并且UI线程似乎也被阻止了,我可以避免这种UI阻止吗?
我使用WebBrowser控件导航到WordPress博客的登录页面.页面加载正常,但每当我尝试从一个线程访问WebBrowser时.我得到一个特定的演员是无效的例外.同样在调试时,一切都冻结了大约5秒钟.调试时,我尝试访问控件.我得到了所有成员变量的错误.
//in constructor of main form
Thread.CurrentThread.ApartmentState = ApartmentState.STA;
this.CheckForIllegalCrossThreadCalls = false;
mainThreadHandle = new Thread(mainThread);
mainThreadHandle.Start();
private void mainThread()
{
wbMain.Navigate("http://example.com/");
//navigating is set to false in the document complete event.
navigating = true;
while (navigating == true)
Thread.Sleep(5000);
try
{
//Where I get the issues
MessageBox.Show(wbMain.DocumentText);
}
catch (Exception e)
{
}
Thread.Sleep(1000);
}
Run Code Online (Sandbox Code Playgroud) 我是c#的新手,我正在尝试构建一个登录网站的程序并返回它的源代码.问题是,我在页面加载时注册了一个事件监听器,但是当我调试它时,它在设置相同的事件后退出,而不是在页面"加载"之后实际执行我想要它做的事情.
这是来源 -
using System;
using System.Windows.Forms;
namespace WIN
{
class Program
{
string url = -snip-;
string username = -snip-;
string password = -snip-;
string task = -snip-;
string action = -snip-;
string timezone = -snip-;
private void Login()
{
Console.WriteLine("Started.");
Console.ReadLine();
Console.WriteLine("Declaring WebBrowser instance browser...");
WebBrowser browser = new WebBrowser();
Console.WriteLine("Done.");
Console.ReadLine();
Console.WriteLine("Registering an event for when the page finishes loading...");
browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(pageLoaded);
Console.WriteLine("Done.");
Console.ReadLine();
Console.WriteLine("Using method Navigate of browser instance with url parameter...");
browser.Navigate(url);
Console.WriteLine("Done."); …Run Code Online (Sandbox Code Playgroud) 我正在使用 BackgroundWorker 并在其中使用 foreach 循环,在其中我创建新线程,等待它完成,然后报告进度并继续 foreach 循环。这就是我要说的:
private void DoWork(object sender, DoWorkEventArgs e) {
var fileCounter = Convert.ToDecimal(fileNames.Count());
decimal i = 0;
foreach (var file in fileNames) {
i++;
var generator = new Generator(assembly);
var thread = new Thread(new ThreadStart(
delegate() {
generator.Generate(file);
}));
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
while (thread.IsAlive); // critical point
int progress = Convert.ToInt32(Math.Round(i / fileCounter * 100));
backgroundWorker.ReportProgress(progress);
}
}
Run Code Online (Sandbox Code Playgroud)
问题是线程完成后(通过“临界点”线后)内存没有被释放。我认为当线程不活动时,与它相关的所有资源都会被释放。但显然这不是真的。任何人都可以向我解释为什么以及我做错了什么。谢谢。
所以我不知道如何提出这个问题,可能是我在任何地方找到问题的原因之一.
所以我的设置是我有一堂课
public class Connection
{
public static event EventHandler LogggedIn;
public static TDConnection TDC {get;set;}
public string Authenticate(){...}
public static void Login()
{
if (Connection.TDC.Connected)
{
_bw = new BackgroundWorker
{
WorkerReportsProgress = true,
WorkerSupportsCancellation = true
};
_bw.DoWork += ConnectToProject_DoWork;
_bw.RunWorkerCompleted += ConnectToProject_RunWorkerCompleted;
_bw.RunWorkerAsync(Connection.TDC);
}
}
private static void ConnectToProject_DoWork(object o, DoWorkEventArgs e)
{
Connection.TDC.ConnectProjectEx(Connection.Domain, Connection.Project, Connection.UserName, Utilities.Encryption.AESEncryption.Decrypt(Connection.Password, "fsd*#(dfs(((>>>???fdjs"));
}
private static void ConnectToProject_RunWorkerCompleted(object o, RunWorkerCompletedEventArgs e)
{
LogggedIn(null, new EventArgs());
}
}
Run Code Online (Sandbox Code Playgroud)
在我的主类中,我实例化一个新的Connection并调用Login,它在TDConnection中打开一个与ALM的新连接.在我的线程中,我想在我的线程中使用这个已经打开的连接.根据我的阅读,如果我这样做,我的UI将阻止因为我在UI线程上使用成员的方法,即使我在后台工作者内部.
我发现这样做的一个解决方案:
private static void …Run Code Online (Sandbox Code Playgroud) 我可以看到这是一个简单的修正,但它让我难过.
这是我得到的错误
COMException未处理
错误HRESULT E_FAIL已从调用COM组件返回.
这是代码(我已经删除了URL,但它们是有效的)
class SMSHandler
{
private InternetExplorer ie;
private object URL = "##########";
private object URL2 = "###########";
public SMSHandler()
{
ie = new InternetExplorer();
ie.Visible = true;
}
public void openMACS()
{
object Empty = 0;
ie.Navigate2(ref URL, ref Empty, ref Empty, ref Empty, ref Empty);
while (ie.Busy);
ie.Navigate2(ref URL2, ref Empty, ref Empty, ref Empty, ref Empty);
IHTMLDocument2 HTMLDoc = (IHTMLDocument2)ie.Document;
}
Run Code Online (Sandbox Code Playgroud)
这是产生错误的行
IHTMLDocument2 HTMLDoc = (IHTMLDocument2)ie.Document;
Run Code Online (Sandbox Code Playgroud)
网页打开正常,但是当我尝试将文档分配给IHTMLDocument2时,它失败了.
任何帮助都会很棒