public delegate void SetListViewCallBack(string type,string str);
public SetListViewCallBack setListViewCallBack = new SetListViewCallBack(SetListView);private void BeginSetListView(string type,string str)
{
setListViewCallBack .BeginInvoke(type, str, EndSetListView, setListViewCallBack );
}public void SetListView(string type, string str)
{
ListViewItem lstViewItem = new ListViewItem();
lstViewItem.SubItems[0].Text = type;
lstViewItem.SubItems.Add(str);
lstViewItem.SubItems.Add(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
lv_users.Items.Add(lstViewItem);
}private void EndSetListView(IAsyncResult ir)
{
SetListViewCallBack callbacktemp = (SetListViewCallBack)ir.AsyncState;
callbacktemp.EndInvoke(ir);
}【lv_users.Items.Add(lstViewItem);】
这一句话就错误了,提示“线程间操作无效: 从不是创建控件“lv_users”的线程访问它”
这个异步操作不是可以对控件赋值么,想问下到底怎么写个公共的方法去异步赋值。
public SetListViewCallBack setListViewCallBack = new SetListViewCallBack(SetListView);private void BeginSetListView(string type,string str)
{
setListViewCallBack .BeginInvoke(type, str, EndSetListView, setListViewCallBack );
}public void SetListView(string type, string str)
{
ListViewItem lstViewItem = new ListViewItem();
lstViewItem.SubItems[0].Text = type;
lstViewItem.SubItems.Add(str);
lstViewItem.SubItems.Add(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
lv_users.Items.Add(lstViewItem);
}private void EndSetListView(IAsyncResult ir)
{
SetListViewCallBack callbacktemp = (SetListViewCallBack)ir.AsyncState;
callbacktemp.EndInvoke(ir);
}【lv_users.Items.Add(lstViewItem);】
这一句话就错误了,提示“线程间操作无效: 从不是创建控件“lv_users”的线程访问它”
这个异步操作不是可以对控件赋值么,想问下到底怎么写个公共的方法去异步赋值。
或者用同步上下文
控件中定义
SynchronizationContext synchronizationContext = SynchronizationContext.Current;
然后在属性中
public 属性名{ set{ synchronizationContext.Post();}}
SynchronizationContext synchronizationContext = SynchronizationContext.Current;
这句话是放在什么地方啊。
public 属性名{ set{ synchronizationContext.Post();}}
这个定义了 怎么使用啊
delegate void SetListViewCallBack(string type, string str); private void BeginSetListView(string type, string str)
{
SetListViewCallBack setListViewCallBack = new SetListViewCallBack(SetListView);
setListViewCallBack.BeginInvoke(type, str, EndSetListView, setListViewCallBack);
}
public void SetListView(string type, string str)
{
ListViewItem lstViewItem = new ListViewItem();
lstViewItem.SubItems[0].Text = type;
lstViewItem.SubItems.Add(str);
lstViewItem.SubItems.Add(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
InvokeSetItem(lstViewItem);//修改处
}
private void EndSetListView(IAsyncResult ir)
{
SetListViewCallBack callbacktemp = (SetListViewCallBack)ir.AsyncState;
callbacktemp.EndInvoke(ir);
}
//以下为新添加
protected delegate void SetItemHander(ListViewItem item);
protected void InvokeSetItem(ListViewItem item)
{
SetItemHander d = new SetItemHander(SetItem);
object arg = (object)item;
this.Invoke(d, arg);
}
protected void SetItem(ListViewItem item)
{
lv_users.Items.Add(item);
}
http://www.cnblogs.com/mokey/articles/2095457.html
//自定义控件
private SynchronizationContext synchronizationContext = SynchronizationContext.Current;
public string Labstr {
set { synchronizationContext.Post(_v => label1.Text = _v.ToString(), value); }
}
//使用控件
//主线程添加控件
UserControl1 userControl11 = new UserControl1() { Location = new Point(0), Size = new Size(200, 200) };
Controls.Add(userControl11);
//后台线程给主线程控件赋值
new Thread(() =>
{
while (true)
{
Thread.Sleep(1000);
userControl11.Labstr = DateTime.Now.ToString();
} }) { IsBackground=true }.Start();
同时下面也有一些示例代码,你也可以参考下面的代码来实现你自己的需求private void btnDownLoad_Click(object sender, EventArgs e)
{
rtbState.Text = "Download............";
btnDownLoad.Enabled = false;
if (txbUrl.Text == string.Empty)
{
MessageBox.Show("Please input valid download file url");
return;
} AsyncMethodCaller methodCaller = new AsyncMethodCaller(DownLoadFileSync);
methodCaller.BeginInvoke(txbUrl.Text.Trim(), GetResult, null); // 捕捉调用线程的同步上下文派生对象
sc = SynchronizationContext.Current;
} // 同步下载文件的方法
// 该方法会阻塞主线程,使用户无法对界面进行操作
// 在文件下载完成之前,用户甚至都不能关闭运行的程序。
private string DownLoadFileSync(string url)
{
// Create an instance of the RequestState
RequestState requestState = new RequestState();
try
{
// Initialize an HttpWebRequest object
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url); // assign HttpWebRequest instance to its request field.
requestState.request = myHttpWebRequest;
requestState.response = (HttpWebResponse)myHttpWebRequest.GetResponse();
requestState.streamResponse = requestState.response.GetResponseStream();
int readSize = requestState.streamResponse.Read(requestState.BufferRead, 0, requestState.BufferRead.Length); while (readSize > 0)
{
requestState.filestream.Write(requestState.BufferRead, 0, readSize);
readSize = requestState.streamResponse.Read(requestState.BufferRead, 0, requestState.BufferRead.Length);
} // 执行该方法的线程是线程池线程,该线程不是与创建richTextBox控件的线程不是一个线程
// 如果不把 CheckForIllegalCrossThreadCalls 设置为false,该程序会出现“不能跨线程访问控件”的异常
return string.Format("The Length of the File is: {0}", requestState.filestream.Length) + string.Format("\nDownLoad Completely, Download path is: {0}", requestState.savepath);
}
catch (Exception e)
{
return string.Format("Exception occurs in DownLoadFileSync method, Error Message is:{0}", e.Message);
}
finally
{
requestState.response.Close();
requestState.filestream.Close();
}
} // 异步操作完成时执行的方法
private void GetResult(IAsyncResult result)
{
AsyncMethodCaller caller = (AsyncMethodCaller)((AsyncResult)result).AsyncDelegate;
// 调用EndInvoke去等待异步调用完成并且获得返回值
// 如果异步调用尚未完成,则 EndInvoke 会一直阻止调用线程,直到异步调用完成
string returnstring = caller.EndInvoke(result); // 通过获得GUI线程的同步上下文的派生对象,
// 然后调用Post方法来使更新GUI操作方法由GUI 线程去执行
sc.Post(ShowState,returnstring);
} // 显示结果到richTextBox
// 因为该方法是由GUI线程执行的,所以当然就可以访问窗体控件了
private void ShowState(object result)
{
rtbState.Text = result.ToString();
btnDownLoad.Enabled = true;
}
}
这个方法可以实现。但是我这也是异步的啊,就是里面没有去invoke。
我如果里面有个lable
直接lbState.Text = “啊啊啊”; 是可以赋值的啊 怎么控件不一样就不能赋值了
{
ListViewItem lstViewItem = new ListViewItem();
lstViewItem.SubItems[0].Text = type;
lstViewItem.SubItems.Add(str);
lstViewItem.SubItems.Add(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
//lv_users.Items.Add(lstViewItem);
//修改为
lbState.Text = “啊啊啊”;
}
就可以了,都是控件。怎么有的可以 有的不可以。
lv_users.Invoke(new Action<ListViewItem>(list)=>
{
lv_users.Items.Add(list)
},lstViewItem
)