跨線程ui訪問
A. wpf中 我新開一個線程添加控制項到主窗體
wpf中使用Dispatcher類控制線程, 當非同步操作完成後, 可以調用
Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() => { //to do sth })); 返回UI線程
B. Android系統為什麼不允許在線程中訪問UI
UI線程及Android的單線程模型原則當應用啟動,系統會創建一個主線程(main thread)。這個主線程負責向UI組件分發事件(包括繪制事件),也是在這個主線程里,應用和Android的UI組件(components from the Android UI toolkit (components from the android.widget and android.view packages))發生交互。
當App做一些比較重(intensive)的工作的時候,除非合理地實現,否則單線程模型的performance會很poor。特別的是,如果所有的工作都在UI線程,做一些比較耗時的工作比如訪問網路或者資料庫查詢,都會阻塞UI線程,導致事件停止分發(包括繪制事件)。對於用戶來說,應用看起來像是卡住了,更壞的情況是,如果UI線程blocked的時間太長(大約超過5秒),用戶就會看到ANR(application not responding)的對話框。
另外,Andoid UI toolkit並不是線程安全的,所以不能從非UI線程來操縱UI組件。必須把所有的UI操作放在UI線程里,所以Android的單線程模型有兩條原則:
1.不要阻塞UI線程。
2.不要在UI線程之外訪問Android UI toolkit(主要是這兩個包中的組件:android.widget and android.view)。
C. WPF跨線程遍歷訪問容器內的控制項
this.Dispatcher.Invoke(new Action(() =>{
//TODO:更新UI控制項操作
}));
D. unity c#跨線程調用怎麼實現
在unity里邊使用多線程做一些事情是非常好的,比如解壓資源 更新資源等。因為單開線程的話 不會影響主線程卡頓,這樣UI就不會卡了。但是開的線程里邊不能執行unity主線程的mono代碼。線程啟動後,執行完畢自動結束該線程、可以同時啟動多個線程做事。
代碼如下: using System.Threading;
void StartThread()
{
Thread athread = new Thread(new ThreadStart(goThread));
athread.IsBackground = true;//防止後台現成。相反需要後台線程就設為false
athread.Start();
}
void Awake()
{
StartThread();
}
object lockd = new object();
void goThread()
{
int index = 0;
while (true)
{
lock (lockd)//防止其他線程訪問當前線程使用的數據
{
Debug.Log("in thread" + index);
index++;
if (index == 100)
{
Thread.Sleep(10000);// 將當前線程掛起指定的時間 毫秒 時間結束後 繼續執行下一步 和yield類似
}
else if (index == 200)
{
break;//該函數執行完自動結束該線程
}
}
}
}
所以其實多線程和協程原理差別很大的,只是功能有點類似。
1、當在主線程中創建了一個線程,那麼該線程的IsBackground默認是設置為FALSE的。
2、當主線程退出的時候,IsBackground=FALSE的線程還會繼續執行下去,直到線程執行結束。
3、只有IsBackground=TRUE的線程才會隨著主線程的退出而退出
---------------------------------------------------------------------------------------------
ThreadStart:
Thread athread = new Thread(new ThreadStart(goThread));
athread.Start();//該方法啟動的多線程 不能帶有參數。
ParameterThreadStart:
ParameterThreadStart的定義為void ParameterizedThreadStart(object state),使用這個這個委託定義的線程的啟動函數可以接受一個輸入參數,具體例子如下 :
[csharp] view plain
ParameterizedThreadStart threadStart=new ParameterizedThreadStart(Calculate)
Thread thread=new Thread() ;
thread.Start(0.9);//參數是0.9
public void Calculate(object arg)//arg參數是0.9
{
double Diameter=double(arg);
Console.Write("The Area Of Circle with a Diameter of {0} is {1}"Diameter,Diameter*Math.PI);
}
Calculate方法只有一個為object類型的參數。需要傳多個參數的時候 需要把參數都塞進object 然後進行轉換。比如:
一個參數 void BuildA(object para){ List<int> list=para as List<int>;...}
BuildA(list);
多個參數 void BuildB(object para){ object[] ps= para as object[];List<int> list=ps[0] as as List<int>;GameObject b=ps[1] as GameObject;...}
BuildB(new object[]{list,obj});//把多個參數塞到object數組里邊 傳過去,相當於只傳一個參數。
至於是開一個線程還是多個線程 根據需求和內核數SystemInfo.processorCount來確定。最好一個核開一個線程 會快點。
詳見bundleglobal.cs和sdFileSystem.cs/sdMultiThread.cs