Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#中使用线程和ListView的一个问题_C#_Multithreading_Listview_Compact Framework_Mobile - Fatal编程技术网

c#中使用线程和ListView的一个问题

c#中使用线程和ListView的一个问题,c#,multithreading,listview,compact-framework,mobile,C#,Multithreading,Listview,Compact Framework,Mobile,我有一个文本过滤器,在TextChanged事件中,我通过以下方式启动listview填充代码: ThreadPool.QueueUserWorkItem(new WaitCallback(populate)); 在populate方法中,我有这样的代码 listView1.BeginUpdate(); listView1.Clear(); // rest of the code listView1.EndUpdate(); 但是listView1.BeginUpdate()调用会产生以

我有一个文本过滤器,在TextChanged事件中,我通过以下方式启动listview填充代码:

ThreadPool.QueueUserWorkItem(new WaitCallback(populate));
在populate方法中,我有这样的代码

listView1.BeginUpdate();
listView1.Clear();

// rest of the code

listView1.EndUpdate();
但是listView1.BeginUpdate()调用会产生以下异常:

System.NotSupportedException was unhandled
  Message="An error message cannot be displayed because an optional resource assembly containing it cannot be found"
  StackTrace:
    at Microsoft.AGL.Common.MISC.HandleAr()
    at System.Windows.Forms.ListView.ntvSetStyleEx()
    at System.Windows.Forms.ListView.BeginUpdate()
    at App.frmSelectClient.populate()
    at WorkItem.doWork()
    at System.Threading.Timer.ring()
  InnerException: 
我做错了什么


我想在后台线程中发布ListView的填充。

除了UI线程之外,您不能从任何线程更新UI元素。使用Control.Invoke/BeginInvoke执行此操作

您可以在后台线程中执行所有数据加载等操作,但需要封送到UI线程以实际填充UI控件本身

<>这是大多数UI框架中的情况,当然是Windows窗体(桌面和CF)和Windows演示基础(在这里使用分派器而不是控件)。
需要注意的一点是:如果我没记错的话,Compact框架只支持Control.Invoke/BeginInvoke的EventHandler委托。不可否认,这一点在最近的版本中可能已经发生了变化。

就像其他文章中提到的那样,要从另一个线程更新ListView,您必须使用BeginInvoke/Invoke以正确的方式进行。我为自己创建了两个线程安全的助手函数(用于ListView和更多控件)。每当我想用listview或控件本身做一些事情时,我只使用下面提到的其中一种。当然,它遗漏了很多其他选项,但到目前为止,我还不需要其他东西,所以我没有创建更多,但它应该向您展示最终将它们添加到列表中的正确方法

internal class GlobalFunctions {
    public static void changeControlStatus(Control varControl, bool varState) {
        if (varControl.InvokeRequired) {
            varControl.BeginInvoke(new ControlStateChange(changeControlStatus), new object[] {varControl, varState});
        } else {
            varControl.Enabled = varState;
        }
    }
    public static void changeControlText(Control varControl, string varText) {
        if (varControl.InvokeRequired) {
            varControl.BeginInvoke(new ControlTextChange(changeControlText), new object[] {varControl, varText});
        } else {
            varControl.Text = varText;
        }
    }
    public static string readControlText(Control varControl) {
        if (varControl.InvokeRequired) {
            return (string) varControl.Invoke(new Func<String>(() => readControlText(varControl)));
        } else {
            string varText = varControl.Text;
            return varText;
        }
    }
    public static int listViewCountItems(ListView varControl) {
        if (varControl.InvokeRequired) {
            return (int) varControl.Invoke(new Func<int>(() => listViewCountItems(varControl)));
        } else {
            return varControl.Items.Count;
            //string varText = varControl.Text;
            //return varText;
        }
    }
    public static void comboBoxClearItems(ComboBox varControl) {
        if (varControl.InvokeRequired) {
            varControl.BeginInvoke(new MethodInvoker(() => comboBoxClearItems(varControl)));
        } else {
            varControl.Items.Clear();
        }
    }
    public static void listViewClearItems(ListView varListView) {
        if (varListView.InvokeRequired) {
            varListView.BeginInvoke(new ListViewHandler(listViewClearItems), new object[] {varListView});
        } else {
            varListView.Items.Clear();
        }
    }
    public static void listViewClearColumns(ListView varListView) {
        if (varListView.InvokeRequired) {
            varListView.BeginInvoke(new ListViewHandler(listViewClearColumns), new object[] {varListView});
        } else {
            varListView.Clear();
        }
    }
    public static void listViewAddItem(ListView varListView, ListViewItem item) {
        if (varListView.InvokeRequired) {
            varListView.BeginInvoke(new MethodInvoker(() => listViewAddItem(varListView, item)));
        } else {
            varListView.Items.Add(item);
        }
    }
    public static void listViewEditItem(ListView varListView, int varRow, int varColumn, string varText) {
        if (varListView.InvokeRequired) {
            varListView.BeginInvoke(new MethodInvoker(() => listViewEditItem(varListView, varRow,varColumn, varText )));
        } else {
            varListView.Items[varRow].SubItems[varColumn].Text = varText;
        }
    }
    public static void listViewEditItemColor(ListView varListView, int varRow, Color varColor) {
        if (varListView.InvokeRequired) {
            varListView.BeginInvoke(new MethodInvoker(() => listViewEditItemColor(varListView, varRow, varColor)));
        } else {
            varListView.Items[varRow].BackColor = varColor;
        }
    }
    public static void listViewChangeBackColor(ListView varListView, ListViewItem item, Color varColor) {
        if (varListView.InvokeRequired) {
            varListView.BeginInvoke(new MethodInvoker(() => listViewChangeBackColor(varListView, item, varColor)));
        } else {
            for (int i = 0; i < varListView.Columns.Count; i++) {
                item.UseItemStyleForSubItems = false;
                item.SubItems[i].BackColor = varColor;
            }
        }
    }
    public static void listViewChangeHeaderStyle(ListView varListView, ColumnHeaderStyle varColumnHeaderStyle) {
        if (varListView.InvokeRequired) {
            varListView.BeginInvoke(new MethodInvoker(() => listViewChangeHeaderStyle(varListView, varColumnHeaderStyle)));
        } else {
            varListView.HeaderStyle = varColumnHeaderStyle;
        }
    }
    public static void listViewAddItemRange(ListView varListView, ListViewItem item) {
        if (varListView.InvokeRequired) {
            varListView.BeginInvoke(new MethodInvoker(() => listViewAddItemRange(varListView, item)));
        } else {
            //varListView.Items.Add(item);
            varListView.Items.AddRange(new[] {item});
        }
    }
    public static void listViewAddColumn(ListView varListView, string varColumnName, int varColumnSize) {
        if (varListView.InvokeRequired) {
            varListView.BeginInvoke(new MethodInvoker(() => listViewAddColumn(varListView, varColumnName, varColumnSize)));
        } else {
            varListView.Columns.Add(varColumnName, varColumnSize, HorizontalAlignment.Left);
        }
    }
    #region Nested type: ControlStateChange
    private delegate void ControlStateChange(Control varControl, bool varState);
    #endregion
    #region Nested type: ControlTextChange
    private delegate void ControlTextChange(Control varControl, string varText);
    #endregion
    private delegate string ControlTextRead(Control varControl);
    #region Nested type: ListViewHandler
    private delegate void ListViewHandler(ListView varListView);
    #endregion
    #region Nested type: ListViewHandlerItem
    private delegate void ListViewHandlerItem(ListView varListView, ListViewItem item);
    #endregion
}
内部类全局函数{
公共静态void changeControlStatus(Control varControl,bool varState){
if(varControl.invokererequired){
BeginInvoke(新的ControlStateChange(changeControlStatus),新对象[]{varControl,varState});
}否则{
varControl.Enabled=varState;
}
}
公共静态void changeControlText(控件varControl,字符串varText){
if(varControl.invokererequired){
BeginInvoke(新的ControlTextChange(changeControlText),新对象[]{varControl,varText});
}否则{
Text=varText;
}
}
公共静态字符串readControlText(Control varControl){
if(varControl.invokererequired){
return(string)varControl.Invoke(newfunc(()=>readControlText(varControl));
}否则{
字符串varText=varControl.Text;
返回varText;
}
}
公共静态int listViewCountItems(ListView变量控件){
if(varControl.invokererequired){
return(int)varControl.Invoke(newfunc(()=>listViewCountItems(varControl));
}否则{
返回varControl.Items.Count;
//字符串varText=varControl.Text;
//返回varText;
}
}
公共静态无效ComboBox ClearItems(ComboBox varControl){
if(varControl.invokererequired){
BeginInvoke(新的MethodInvoker(()=>comboBoxClearItems(varControl));
}否则{
varControl.Items.Clear();
}
}
公共静态无效listViewClearItems(ListView varListView){
if(varListView.invokererequired){
BeginInvoke(新ListViewHandler(listViewClearItems),新对象[]{varListView});
}否则{
varListView.Items.Clear();
}
}
公共静态无效listViewClearColumns(ListView varListView){
if(varListView.invokererequired){
BeginInvoke(新ListViewHandler(listViewClearColumns),新对象[]{varListView});
}否则{
varListView.Clear();
}
}
公共静态无效listViewAddItem(ListView变量ListView,ListViewItem项){
if(varListView.invokererequired){
BeginInvoke(新方法调用程序(()=>listViewAddItem(varListView,项));
}否则{
varListView.Items.Add(item);
}
}
公共静态void listViewEditItem(ListView-varListView、int-varRow、int-varColumn、string-varText){
if(varListView.invokererequired){
BeginInvoke(新方法调用程序(()=>listViewEditItem(varListView、varRow、varColumn、varText));
}否则{
varListView.Items[varRow]。子项[varColumn]。Text=varText;
}
}
公共静态void listViewEditItemColor(ListView varListView、int varRow、Color varColor){
if(varListView.invokererequired){
BeginInvoke(新方法调用程序(()=>listViewEditItemColor(varListView,varRow,varColor));
}否则{
varListView.Items[varRow].BackColor=varColor;
}
}
公共静态无效listViewChangeBackColor(ListView varListView,ListViewItem项,Color varColor){
if(varListView.invokererequired){
BeginInvoke(新方法调用程序(()=>listViewChangeBackColor(varListView,item,varColor));
}否则{
对于(int i=0;ilistViewChangeHeaderStyle(varListView,varColumnHeaderStyle));
}否则{
varListView.HeaderStyle=varColumnHeaderStyle;
}
}
公共静态无效listViewAddItemRange(ListView变量ListView,ListViewItem项){
if(varListView.invokererequired){
BeginInvoke(新方法调用程序(()=>listViewAddItemRange(varListView,项));
}否则{
//varListView.Items.Add(item);
varListView.Items.AddRange(新[]{item