我有一个类,它有一些创建和发生的任务。当我运行我的测试应用程序时,创建/使用的线程的示例如下...
我能够将一个对象从我的主线程(9)传递到一个工作线程(10),并从工作线程传递给工作者ContinueWith线程(11)[AKA完成工作线程(10) )]。我所做的一切都很好,有一个例外......我似乎无法使用类似事件的东西将该对象恢复到主线程。每当我尝试委托或调用回主线程时,它都无法工作。它总是在Thread11而不是Thread9上激活!
我的目标是将对象(在Thread11中使用)返回到主Thread9。
注意:
更新 - 示例:
private SQLConnectionProperties sql = new SQLConnectionProperties();
private void SQLTest()
{
//Being called from main UI thread 9
sql.SQLErrorMessage = "FIRST CHANGE";
Task<SQLConnectionProperties> taskConnect = Task.Factory
.StartNew(() => threadConnect(sql), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default)
.ContinueWith((task) => threadConnect(task.Result, true));
//Continue back to main UI (still in main UI thread 9)
}
private SQLConnectionProperties threadConnect(SQLConnectionProperties sql, bool bContinuation = false)
{
if (!bContinuation)
{
//In new thread 10
sql.SQLErrorMessage = "SECOND CHANGE";
}
else
{
//In new thread 11
sql.SQLErrorMessage = "THIRD CHANGE";
}
return sql;
}
使用上面的代码,我会得到我想要的所有内容,直到In new thread 11
行。在SQLErrorMessage更改为&#34; THIRD CHANGE&#34;并且它返回我需要引发某种类型的事件或者将结果返回到主UI线程9。
答案 0 :(得分:0)
您需要使用_synchronizationContext.Send
或_synchronizationContext.Post
与UI线程进行通信。
另外,根据你提到的内容,我认为你还需要通过&#34; false&#34;当调用上述任何一个函数时,它知道该函数不是从UI线程调用的。
_synchronizationContext = SynchronizationContext.Current
答案 1 :(得分:0)
正如@ r00tdev所解释的那样,使用SynchronizationContext()类是我尝试做的解决方案。下面你将看到我如何使用它来将工作线程的结果返回到主UI线程的示例。谢谢你的答案@ r00tdev!
示例:
private void SQLTest()
{
//Set up a sync context back to this main UI thread
m_sql.SyncContext = SynchronizationContext.Current;
//Being called from main UI thread 9
m_sql.SQLErrorMessage = "FIRST CHANGE";
Task<SQLConnectionProperties> taskConnect = Task.Factory
.StartNew(() => threadConnect(m_sql), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default)
.ContinueWith((task) => threadConnect(task.Result, true));
//Continue back to main UI (still in main UI thread 9)
}
private SQLConnectionProperties threadConnect(SQLConnectionProperties sql, bool bContinuation = false)
{
if (!bContinuation)
{
//In new thread 10
sql.SQLErrorMessage = "SECOND CHANGE";
}
else
{
//In new thread 11
sql.SQLErrorMessage = "THIRD CHANGE";
sql.SyncContext.Post(threadConnectComplete, sql);
}
return sql;
}
private void threadConnectComplete(object state)
{
//Back in the main UI thread! Save the changes to the sql object
SQLConnectionProperties sql = state as SQLConnectionProperties;
m_sql = sql;
//See the results and use this area to update the main UI
Debug.WriteLine("SQLErrorMessage:" + sql.SQLErrorMessage);
//TESTING NON THREAD SAFE just to show you no runtime errors happen
form_MainUI.textbox1.Text = sql.SQLErrorMessage;
}