Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.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

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
.net 从单独的线程添加菜单项_.net_Multithreading_Compact Framework_.net 2.0 - Fatal编程技术网

.net 从单独的线程添加菜单项

.net 从单独的线程添加菜单项,.net,multithreading,compact-framework,.net-2.0,.net,Multithreading,Compact Framework,.net 2.0,我在一个单独的线程中创建菜单项,并将它们添加到主线程中创建的菜单中。我正在使用Invoke。获取“值不在预期范围内”异常 //creating new thread Thread thread = new Thread(LoadRecentTasks); thread.IsBackground = true; thread.Start(); private void LoadRecentTa

我在一个单独的线程中创建菜单项,并将它们添加到主线程中创建的菜单中。我正在使用Invoke。获取“值不在预期范围内”异常

            //creating new thread
            Thread thread = new Thread(LoadRecentTasks);
            thread.IsBackground = true;
            thread.Start();

    private void LoadRecentTasks()
    {
        EntryCollection recentEntries = Entry.GetRecentEntries(10);
        foreach (Entry entry in recentEntries)
        {
            MenuItemPlus menuItem = new MenuItemPlus();
            menuItem.Text = entry.GetShortDescription(28);
            menuItem.Click += recentTasksMenuItem_Click;
            menuItem.Tag = entry;
            AddRecentMenuItem(menuItem);
        }
    }

    private void AddRecentMenuItem(MenuItemPlus menuItem)
    {
        if (InvokeRequired)
        {
            BeginInvoke(new CallbackDelegate<MenuItemPlus>(AddRecentMenuItem), menuItem);
        }
        else
        {
            menuItemRecent.MenuItems.Add(menuItem); //<-- exception thrown here
        }
    }

    delegate void CallbackDelegate<T>(T t);
//创建新线程
线程线程=新线程(LoadRecentTasks);
thread.IsBackground=true;
thread.Start();
私有void LoadRecentTasks()
{
EntryCollection recentEntries=Entry.getRecentries(10);
foreach(最近的条目)
{
menuitempus menuItem=新的menuitempus();
menuItem.Text=entry.GetShortDescription(28);
menuItem.Click+=recentTasksMenuItem\u单击;
menuItem.Tag=条目;
AddRecentMenuItem(menuItem);
}
}
私有void AddRecentMenuItem(MenuTempus menuItem)
{
如果(需要调用)
{
BeginInvoke(新CallbackDelegate(AddRecentMenuItem)、menuItem);
}
其他的
{

menuItemRecent.MenuItems.Add(menuItem);//我假设在未完全创建控件时会发生这种情况,从而导致invokererequired提供错误的读数

      /// <summary>
  /// It's possible for InvokeRequired to return false when running in background thread.
  /// This happens when unmanaged control handle has not yet been created (need to throw).
  /// This can also happen when control is created on background thread (need to debug.assert).
  /// </summary>
  /// <param name="control">Control to check against.</param>
  public bool InvokeRequired(Control control)
  {
     return InvokeRequired(control, false);
  }

  /// <param name="backgroundControl">If set to true, will not assert when control on background thread. </param>
  public bool InvokeRequired(Control control, bool controlOnBackgroundByDesign)
  {
     if (control.InvokeRequired)
        return true;

     if (!control.IsHandleCreated)
        Debug.WriteLine("Control access issue: Underlying control handle has not been created yet.  At this point in time cannot reliably test if invoke is required.");

     if (!controlOnBackgroundByDesign)
     {
        // Check for control on background thread.
        if(!this.IsOnUiThread)
           Debug.WriteLine("Control access issue: It's recommended that all controls reside on a single foreground thread.");
     }

     // At this point, program is executing on control's thread.
     return false;
  }
//
///在后台线程中运行时,invokererequired可能返回false。
///如果尚未创建非托管控件句柄(需要抛出),则会发生这种情况。
///在后台线程上创建控件时也会发生这种情况(需要debug.assert)。
/// 
///控件进行检查。
需要公共布尔调用(控制)
{
返回invokererequired(控件,false);
}
///如果设置为true,则在后台线程上执行控件时不会断言。
需要公共bool调用(控制控制,bool控制背景设计)
{
if(control.invokererequired)
返回true;
如果(!control.IsHandleCreated)
WriteLine(“控件访问问题:尚未创建底层控件句柄。此时无法可靠地测试是否需要调用。”);
if(!controlOnBackgroundByDesign)
{
//检查后台线程上的控件。
如果(!this.IsOnUiThread)
WriteLine(“控件访问问题:建议所有控件都驻留在一个前台线程上。”);
}
//此时,程序正在控件的线程上执行。
返回false;
}

Hmmmm。每当我打电话给BeginInvoke时,我总是这样做:

BeginInvoke(new CallbackDelegate<MenuItemPlus>(AddRecentMenuItem), new object[]{menuItem});
BeginInvoke(新回调委托(AddRecentMenuItem),新对象[]{menuItem});

IIRC正确地说,我总是使用对象数组,因为在过去没有对象数组,我会遇到奇怪的异常。

哪一行代码会引发异常?我假设是他评论的那一行:)出于某种原因,我认为BeginInvoke需要一个参数数组而不是一个对象,但如果是这样的话,我怀疑代码是否能够编译。@SimonJ.哈哈,我是瞎子还是瞎子?听起来很合理…当然,这个代码示例不完整,所以我不可能为你重新编译和调试。谢谢,Greg。menuItemRecent是作为表单初始化例程的一部分创建的。线程是在表单的激活事件上启动的。你有机会尝试提供的InvokeRequired替换吗Monte?它是否按计划工作,或者您是否在调试输出面板中收到一些消息?我认为InvokeRequired不可能在CF中给出错误的值。CF中控件上的InvokeRequired非常简单。它只需要在Ctor中创建它的线程id,然后将它与InvokeRequired中的当前线程id进行比较。我已经用y尝试过了我们的代码。两个问题:IsHandleCreated和IsUnuithRead在不可用的地方(我使用了.NET CF 2.0)我尝试了(control.Handle==IntPtr.Zero)而不是(!control.IsHandleCreated)-从未出现过这种情况。我在想,可能可以在主UI线程中创建菜单项,但可以将对象引用返回到第二个线程。伪代码:LoadRecentTasks(){foreach(recentEntries中的条目){AddRecentMenuItem(MainUIThread.NewMenuItem());}}