Sme*_*iff 1 c# multithreading backgroundworker alm threadpool
所以我不知道如何提出这个问题,可能是我在任何地方找到问题的原因之一.
所以我的设置是我有一堂课
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 ConnectToProject_DoWork(object o, DoWorkEventArgs e)
{
TDConnection conn = new TDConnection();
conn.InitConnectionEx(QCURL);
conn.Login();
conn.ConnectProject();
e.Result = conn;
}
Run Code Online (Sandbox Code Playgroud)
我不想这样做,因为我已经登录了,这需要额外的时间来完成.
我已经尝试使用_bw.RunorkerAsync(Connection.TDC)传递Connection.TDC,但这显然不起作用.
有什么方法可以使用已经建立的连接,而不是在连接时阻止UI?
这在COM对象中很常见.就像.NET类一样,许多COM coclass都不是线程安全的.在.NET中,如果以线程不安全的方式使用.NET类,则可以自己动手.不在COM中,它保证了一个宣称自己不是线程安全的coclass将以线程安全的方式使用.
它通过自动封送从工作线程到创建对象的线程的方法调用来完成.你可以看到它在哪里,你在主线程上创建了TDC对象.所以,当你从BackgroundWorker的调用它,它将仍然执行主线程中调用.
解决此问题的唯一方法是在您使用它的同一个线程上创建对象.这通常也意味着您不能使用BackgroundWorker,您可能需要创建一个Thread并调用其SetApartmentState()方法将其切换到STA.