線程訪問控制項
㈠ C#多線程如何調用主線程創建的控制項
1.新開的線程是無法直接訪問UI控制項的,如果需要訪問,可以通過控制項的Invoke方法,或者用
System.Threading.SynchronizationContext.Current.Post方法
2.一定不要在控制項的內部事件處理方法裡面使用Sleep等線程暫停方法!
像我這樣寫就不會阻塞了:
private void button1_Click(object sender, EventArgs e)
{
System.Threading.Thread thread = new System.Threading.Thread(() =>
{
while (true)
{
this.Invoke(new Action(() =>
{
label1.Text = (count++).ToString();
}));
System.Threading.Thread.Sleep(100);
}
});
thread.IsBackground = true;
thread.Start();
}
你把setmess這個線程方法Invoke到了UI的主線程上了,而這個線程裡面有暫停方法,所以呢主線程也會暫停卡住。
而我的方法只是把「label1.Text = (count++).ToString();」Invoke到主線程,而那個新的線程並沒有Invoke到主線程,所以在那個線程裡面使用暫停就沒事了!
假如有一個操作比較費時,或者需要等待之類的,就像我這樣開始一個新的線程,所以的等待操作,費時的操作都在在這個線程裡面做,當這些線程需要訪問UI控制項的時候,就用this.Invoke()這個方法!
㈡ c# 跨線程訪問控制項
用委託,具體代碼如下~:
public delegate void MyInvoke(string str);
private void button9_Click(object sender, EventArgs e)
{
//_myInvoke = new MyInvoke(SetText);
// = false;
Thread t = new Thread(new ThreadStart(fun));
t.Start();
}
private void fun()
{
//_myInvoke("dddd");
SetText("ddd");
}
private void SetText(string s)
{
if (textBox6.InvokeRequired)
{
MyInvoke _myInvoke = new MyInvoke(SetText);
this.Invoke(_myInvoke, new object[] { s });
}
else
{
this.textBox6.Text = s;
}
}
㈢ WPF跨線程遍歷訪問容器內的控制項
this.Dispatcher.Invoke(new Action(() =>{
//TODO:更新UI控制項操作
}));
㈣ Delphi多線程訪問控制項時,主線程可以順利訪問,副線程訪問時就卡死 求解釋
對於涉及VCL的線程,是必須在主線程中的,在DELPHI中使用線程,你只需要記住兩句:
1、線程不安全,2、VCL相關要放到主線程。
㈤ c#子線程如何訪問子窗體中的控制項
控制項聲明成public
然後得到窗體的引用,直接可以訪問。如果窗體不是在子線程中創建的,需要使用Invoke來訪問。
㈥ C#如何在線程中訪問控制項對象
利用ListView.Invoke解決跨線程安全調用,關鍵代碼如下:
voidFindFileInDir(){
if(listView2.InvokeRequired)
{
//跨線程調用
listView2.Invoke(newMethodInvoker(delegate
{
listView2.Items.Add(path);
}));
}
else
{
//直接調用
listView2.Items.Add(path);
}
}//EndofFindFileInDir
㈦ C#中多線程裡面如何調用控制項
定義委託,然後用invoke
private void ucMidPartsid_Load(object sender, EventArgs e)
{
if (is_Load == true)
{
thread = new Thread(new ThreadStart(this.LoadData));
thread.Start();
}
//if (datafinish != null)
//{
// datafinish(this, e);
//}
}
private void LoadData()
{
QueryDataCallBack deleg;
deleg = new QueryDataCallBack(this.DataBinding);
this.Invoke(deleg,null);
}
private void DataBinding()
{
partstableAdapter = new GreatWall.SCM.Parts.DataAccess.DAParts.PartsTableAdapter();
partstableAdapter.Fill(dsParts.GB_PARTS);
cobMidPartsid.DataSource = dsParts.GB_PARTS;
cobMidPartsid.DisplayMember = "B_PARTSID";
cobMidPartsid.ValueMember = "B_ID";
EventArgs e = new EventArgs();
if (datafinish != null)
{
finish = true;
datafinish(this, e);
}
}
㈧ 如何跨線程調用.NET Windows窗體控制項
(1)窗體及控制項
(2)窗體代碼Form1.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Threading;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// 啟動線程
Thread t = new Thread(MyThread);
t.IsBackground = true;
t.Start();
}
void MyThread()
{
while (true)
{
// 在控制項label1上顯示日期和時間
UpdateLabel(DateTime.Now);
Thread.Sleep(1000);
}
}
// 1. 聲明一個委託
delegate void UpdateLableDelegate(DateTime dt);
private void UpdateLabel(DateTime dt)
{
if (label1.InvokeRequired)
{
// 跨線程更新label1處理
UpdateLableDelegate del =
new UpdateLableDelegate(UpdateLabel);
label1.Invoke(del, dt);
}
else
{
// 顯示日期和時間
label1.Text = dt.ToString("yyyy-MM-dd HH:mm:ss");
}
}
}
}
㈨ C#怎麼跨線程訪問控制項
只能用委託,不推薦 = false; 這種做法。
推薦一個封裝好的 InvokeHelper 類(http://www.cnblogs.com/conmajia/archive/2012/08/05/multithread-gui-invoker.html),使用時只需要:
InvokeHelper.Invoke(<控制項名>,"<方法名稱>",<參數>);
InvokeHelper.Get(<控制項名>,"<屬性名稱>");
InvokeHelper.Set(<控制項名>,"<屬性名稱>",<屬性值>);
即可。
㈩ C# 子線程訪問主窗體控制項
是的,
在其他線程里,不允許調用主線程創建的控制項~!!!!
這樣做,是不安全的,因此,2.0屏蔽了這個~
樓上說的很對,用委託,具體代碼如下~:
public delegate void MyInvoke(string str);
private void button9_Click(object sender, EventArgs e)
{
//_myInvoke = new MyInvoke(SetText);
// = false;
Thread t = new Thread(new ThreadStart(fun));
t.Start();
}
private void fun()
{
//_myInvoke("dddd");
SetText("ddd");
}
private void SetText(string s)
{
if (textBox6.InvokeRequired)
{
MyInvoke _myInvoke = new MyInvoke(SetText);
this.Invoke(_myInvoke, new object[] { s });
}
else
{
this.textBox6.Text = s;
}
}