mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2024-11-25 14:27:26 +01:00
CA-286291: Fix the crash when quickly and repeatedly popping up Migrate-to-Server menu (#2018)
* CA-286291: Fix the crash when quickly and repeatedly popping up Migrate-to-Server menu. * Update the thread model. Signed-off-by: Michael Zhao <michael.zhao@citrix.com> * Fix an error in using _stopped flag.
This commit is contained in:
parent
21d6080464
commit
1a8f19ba69
@ -55,8 +55,8 @@ namespace XenAdmin.Commands
|
|||||||
{
|
{
|
||||||
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
private readonly vm_operations _operation;
|
private readonly vm_operations _operation;
|
||||||
private ProduceConsumerQueue workerQueueWithouWlb;
|
|
||||||
private readonly bool _resumeAfter;
|
private readonly bool _resumeAfter;
|
||||||
|
private HostListUpdater hostListUpdater;
|
||||||
|
|
||||||
protected VMOperationToolStripMenuItem(Command command, bool inContextMenu, vm_operations operation)
|
protected VMOperationToolStripMenuItem(Command command, bool inContextMenu, vm_operations operation)
|
||||||
: base(command, inContextMenu)
|
: base(command, inContextMenu)
|
||||||
@ -73,19 +73,16 @@ namespace XenAdmin.Commands
|
|||||||
base.DropDownItems.Add(new ToolStripMenuItem());
|
base.DropDownItems.Add(new ToolStripMenuItem());
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _isDropDownClosed;
|
|
||||||
|
|
||||||
protected override void OnDropDownClosed(EventArgs e)
|
protected override void OnDropDownClosed(EventArgs e)
|
||||||
{
|
{
|
||||||
base.OnDropDownClosed(e);
|
base.OnDropDownClosed(e);
|
||||||
workerQueueWithouWlb.CancelWorkers(false);
|
hostListUpdater.Stop();
|
||||||
_isDropDownClosed = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected override void OnDropDownOpening(EventArgs e)
|
protected override void OnDropDownOpening(EventArgs e)
|
||||||
{
|
{
|
||||||
base.DropDownItems.Clear();
|
base.DropDownItems.Clear();
|
||||||
_isDropDownClosed = false;
|
|
||||||
|
|
||||||
// Work around bug in tool kit where disabled menu items show their dropdown menus
|
// Work around bug in tool kit where disabled menu items show their dropdown menus
|
||||||
if (!Enabled)
|
if (!Enabled)
|
||||||
@ -110,7 +107,6 @@ namespace XenAdmin.Commands
|
|||||||
base.DropDownItems.Add(new VMOperationToolStripMenuSubItem(Messages.HOME_SERVER_MENU_ITEM, Images.StaticImages._000_ServerHome_h32bit_16));
|
base.DropDownItems.Add(new VMOperationToolStripMenuSubItem(Messages.HOME_SERVER_MENU_ITEM, Images.StaticImages._000_ServerHome_h32bit_16));
|
||||||
}
|
}
|
||||||
|
|
||||||
workerQueueWithouWlb = new ProduceConsumerQueue(25);
|
|
||||||
List<Host> hosts = new List<Host>(connection.Cache.Hosts);
|
List<Host> hosts = new List<Host>(connection.Cache.Hosts);
|
||||||
hosts.Sort();
|
hosts.Sort();
|
||||||
foreach (Host host in hosts)
|
foreach (Host host in hosts)
|
||||||
@ -120,174 +116,12 @@ namespace XenAdmin.Commands
|
|||||||
base.DropDownItems.Add(item);
|
base.DropDownItems.Add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// start a new thread to evaluate which hosts can be used.
|
|
||||||
ThreadPool.QueueUserWorkItem(delegate
|
|
||||||
{
|
|
||||||
SelectedItemCollection selection = Command.GetSelection();
|
|
||||||
Session session = selection[0].Connection.DuplicateSession();
|
|
||||||
if (Helpers.WlbEnabled(selection[0].Connection))
|
|
||||||
{
|
|
||||||
WlbRecommendations recommendations = new WlbRecommendations(selection.AsXenObjects<VM>(), session);
|
|
||||||
recommendations.Initialize();
|
|
||||||
|
|
||||||
if (recommendations.IsError)
|
|
||||||
EnableAppropriateHostsNoWlb(session);
|
|
||||||
else
|
|
||||||
EnableAppropriateHostsWlb(session, recommendations);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
EnableAppropriateHostsNoWlb(session);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EnableAppropriateHostsWlb(Session session, WlbRecommendations recommendations)
|
|
||||||
{
|
|
||||||
SelectedItemCollection selection = Command.GetSelection();
|
SelectedItemCollection selection = Command.GetSelection();
|
||||||
// set the first menu item to be the WLB optimal server menu item
|
Session session = selection[0].Connection.DuplicateSession();
|
||||||
VMOperationToolStripMenuSubItem firstItem = (VMOperationToolStripMenuSubItem)base.DropDownItems[0];
|
|
||||||
var firstItemCmd = new VMOperationWlbOptimalServerCommand(Command.MainWindowCommandInterface, selection, _operation, recommendations);
|
|
||||||
var firstItemCmdCanExecute = firstItemCmd.CanExecute();
|
|
||||||
|
|
||||||
Program.Invoke(Program.MainWindow, delegate
|
|
||||||
{
|
|
||||||
firstItem.Command = firstItemCmd;
|
|
||||||
firstItem.Enabled = firstItemCmdCanExecute;
|
|
||||||
});
|
|
||||||
|
|
||||||
List<VMOperationToolStripMenuSubItem> hostMenuItems = new List<VMOperationToolStripMenuSubItem>();
|
|
||||||
foreach (VMOperationToolStripMenuSubItem item in base.DropDownItems)
|
|
||||||
{
|
|
||||||
Host host = item.Tag as Host;
|
|
||||||
if (host != null)
|
|
||||||
{
|
|
||||||
var cmd = new VMOperationWlbHostCommand(Command.MainWindowCommandInterface, selection, host, _operation, recommendations.GetStarRating(host));
|
|
||||||
var canExecute = cmd.CanExecute();
|
|
||||||
|
|
||||||
Program.Invoke(Program.MainWindow, delegate
|
|
||||||
{
|
|
||||||
item.Command = cmd;
|
|
||||||
item.Enabled = canExecute;
|
|
||||||
});
|
|
||||||
hostMenuItems.Add(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shuffle the list to make it look cool
|
hostListUpdater = new HostListUpdater();
|
||||||
// Helpers.ShuffleList(hostMenuItems);
|
hostListUpdater.updateHostList(this, session);
|
||||||
|
|
||||||
// sort the hostMenuItems by star rating
|
|
||||||
hostMenuItems.Sort(new WlbHostStarCompare());
|
|
||||||
|
|
||||||
// refresh the drop-down-items from the menuItems.
|
|
||||||
foreach (VMOperationToolStripMenuSubItem menuItem in hostMenuItems)
|
|
||||||
{
|
|
||||||
Program.Invoke(Program.MainWindow, delegate()
|
|
||||||
{
|
|
||||||
base.DropDownItems.Insert(hostMenuItems.IndexOf(menuItem) + 1, menuItem);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Program.Invoke(Program.MainWindow, () => AddAdditionalMenuItems(selection));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EnableAppropriateHostsNoWlb(Session session)
|
|
||||||
{
|
|
||||||
SelectedItemCollection selection = Command.GetSelection();
|
|
||||||
IXenConnection connection = selection[0].Connection;
|
|
||||||
|
|
||||||
VMOperationCommand cmdHome = new VMOperationHomeServerCommand(Command.MainWindowCommandInterface, selection, _operation, session);
|
|
||||||
Host affinityHost = connection.Resolve(((VM)Command.GetSelection()[0].XenObject).affinity);
|
|
||||||
|
|
||||||
Program.Invoke(Program.MainWindow, delegate
|
|
||||||
{
|
|
||||||
var firstItem = (VMOperationToolStripMenuSubItem)base.DropDownItems[0];
|
|
||||||
|
|
||||||
bool oldMigrateToHomeCmdCanRun = cmdHome.CanExecute();
|
|
||||||
if (affinityHost == null || _operation == vm_operations.start_on || oldMigrateToHomeCmdCanRun)
|
|
||||||
{
|
|
||||||
firstItem.Command = cmdHome;
|
|
||||||
firstItem.Enabled = oldMigrateToHomeCmdCanRun;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
VMOperationCommand cpmCmdHome = new CrossPoolMigrateToHomeCommand(Command.MainWindowCommandInterface, selection, affinityHost);
|
|
||||||
|
|
||||||
if (cpmCmdHome.CanExecute())
|
|
||||||
{
|
|
||||||
firstItem.Command = cpmCmdHome;
|
|
||||||
firstItem.Enabled = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
firstItem.Command = cmdHome;
|
|
||||||
firstItem.Enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
List<VMOperationToolStripMenuSubItem> dropDownItems = DropDownItems.Cast<VMOperationToolStripMenuSubItem>().ToList();
|
|
||||||
|
|
||||||
// Adds the migrate wizard button, do this before the enable checks on the other items
|
|
||||||
Program.Invoke(Program.MainWindow, () => AddAdditionalMenuItems(selection));
|
|
||||||
|
|
||||||
foreach (VMOperationToolStripMenuSubItem item in dropDownItems)
|
|
||||||
{
|
|
||||||
if (_isDropDownClosed)
|
|
||||||
{
|
|
||||||
// Stop making requests to assert can start on each host after dropdown is closed
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Host host = item.Tag as Host;
|
|
||||||
if (host != null)
|
|
||||||
{
|
|
||||||
// API calls could happen in CanExecute(), which take time to wait.
|
|
||||||
// So a Producer-Consumer-Queue with size 25 is used here to :
|
|
||||||
// 1. Make API calls for different menu items happen in parallel;
|
|
||||||
// 2. Limit the count of concurrent threads (now it's 25).
|
|
||||||
workerQueueWithouWlb.EnqueueItem(() =>
|
|
||||||
{
|
|
||||||
if (_isDropDownClosed)
|
|
||||||
return;
|
|
||||||
VMOperationCommand cmd = new VMOperationHostCommand(Command.MainWindowCommandInterface, selection, delegate { return host; }, host.Name().EscapeAmpersands(), _operation, session);
|
|
||||||
CrossPoolMigrateCommand cpmCmd = new CrossPoolMigrateCommand(Command.MainWindowCommandInterface, selection, host, _resumeAfter);
|
|
||||||
|
|
||||||
VMOperationToolStripMenuSubItem tempItem = item;
|
|
||||||
bool oldMigrateCmdCanRun = cmd.CanExecute();
|
|
||||||
if ((_operation == vm_operations.start_on) || oldMigrateCmdCanRun)
|
|
||||||
{
|
|
||||||
Program.Invoke(Program.MainWindow, delegate
|
|
||||||
{
|
|
||||||
tempItem.Command = cmd;
|
|
||||||
tempItem.Enabled = oldMigrateCmdCanRun;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bool crossPoolMigrateCmdCanRun = cpmCmd.CanExecute();
|
|
||||||
if (crossPoolMigrateCmdCanRun || !string.IsNullOrEmpty(cpmCmd.CantExecuteReason))
|
|
||||||
{
|
|
||||||
Program.Invoke(Program.MainWindow, delegate
|
|
||||||
{
|
|
||||||
tempItem.Command = cpmCmd;
|
|
||||||
tempItem.Enabled = crossPoolMigrateCmdCanRun;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Program.Invoke(Program.MainWindow, delegate
|
|
||||||
{
|
|
||||||
tempItem.Command = cmd;
|
|
||||||
tempItem.Enabled = oldMigrateCmdCanRun;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -297,33 +131,262 @@ namespace XenAdmin.Commands
|
|||||||
/// <param name="selection"></param>
|
/// <param name="selection"></param>
|
||||||
protected virtual void AddAdditionalMenuItems(SelectedItemCollection selection) { return; }
|
protected virtual void AddAdditionalMenuItems(SelectedItemCollection selection) { return; }
|
||||||
|
|
||||||
/// <summary>
|
private class HostListUpdater
|
||||||
/// This class is an implementation of the 'IComparer' interface
|
|
||||||
/// for sorting vm placement menuItem List when wlb is enabled
|
|
||||||
/// </summary>
|
|
||||||
private class WlbHostStarCompare : IComparer<VMOperationToolStripMenuSubItem>
|
|
||||||
{
|
{
|
||||||
public int Compare(VMOperationToolStripMenuSubItem x, VMOperationToolStripMenuSubItem y)
|
private ProduceConsumerQueue workerQueueWithoutWlb;
|
||||||
|
readonly object _locker = new object();
|
||||||
|
private bool _stopped;
|
||||||
|
|
||||||
|
private bool Stopped
|
||||||
{
|
{
|
||||||
int result = 0;
|
set
|
||||||
|
{
|
||||||
|
lock (_locker)
|
||||||
|
{
|
||||||
|
_stopped = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (_locker)
|
||||||
|
{
|
||||||
|
return _stopped;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if x and y are enabled, compare their start rating
|
public void Stop()
|
||||||
if (x.Enabled && y.Enabled)
|
{
|
||||||
result = y.StarRating.CompareTo(x.StarRating);
|
Stopped = true;
|
||||||
|
if (workerQueueWithoutWlb != null)
|
||||||
|
workerQueueWithoutWlb.CancelWorkers(false);
|
||||||
|
}
|
||||||
|
|
||||||
// if x and y are disabled, they are equal
|
public void updateHostList(VMOperationToolStripMenuItem menu, Session session)
|
||||||
else if (!x.Enabled && !y.Enabled)
|
{
|
||||||
result = 0;
|
Stopped = false;
|
||||||
|
|
||||||
// if x is disabled, y is greater
|
ThreadPool.QueueUserWorkItem(delegate
|
||||||
else if (!x.Enabled)
|
{
|
||||||
result = 1;
|
if (Stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
// if y is disabled, x is greater
|
SelectedItemCollection selection = menu.Command.GetSelection();
|
||||||
else if (!y.Enabled)
|
if (Helpers.WlbEnabled(selection[0].Connection))
|
||||||
result = -1;
|
{
|
||||||
|
WlbRecommendations recommendations = new WlbRecommendations(selection.AsXenObjects<VM>(), session);
|
||||||
|
recommendations.Initialize();
|
||||||
|
if (Stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
return result;
|
if (recommendations.IsError)
|
||||||
|
EnableAppropriateHostsNoWlb(menu, session);
|
||||||
|
else
|
||||||
|
EnableAppropriateHostsWlb(menu, session, recommendations);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EnableAppropriateHostsNoWlb(menu, session);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EnableAppropriateHostsWlb(VMOperationToolStripMenuItem menu, Session session, WlbRecommendations recommendations)
|
||||||
|
{
|
||||||
|
SelectedItemCollection selection = menu.Command.GetSelection();
|
||||||
|
// set the first menu item to be the WLB optimal server menu item
|
||||||
|
VMOperationToolStripMenuSubItem firstItem = (VMOperationToolStripMenuSubItem)menu.DropDownItems[0];
|
||||||
|
var firstItemCmd = new VMOperationWlbOptimalServerCommand(menu.Command.MainWindowCommandInterface, selection, menu._operation, recommendations);
|
||||||
|
var firstItemCmdCanExecute = firstItemCmd.CanExecute();
|
||||||
|
|
||||||
|
if (Stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Program.Invoke(Program.MainWindow, delegate
|
||||||
|
{
|
||||||
|
firstItem.Command = firstItemCmd;
|
||||||
|
firstItem.Enabled = firstItemCmdCanExecute;
|
||||||
|
});
|
||||||
|
|
||||||
|
List<VMOperationToolStripMenuSubItem> hostMenuItems = new List<VMOperationToolStripMenuSubItem>();
|
||||||
|
foreach (VMOperationToolStripMenuSubItem item in menu.DropDownItems)
|
||||||
|
{
|
||||||
|
Host host = item.Tag as Host;
|
||||||
|
if (host != null)
|
||||||
|
{
|
||||||
|
var cmd = new VMOperationWlbHostCommand(menu.Command.MainWindowCommandInterface, selection, host, menu._operation, recommendations.GetStarRating(host));
|
||||||
|
var canExecute = cmd.CanExecute();
|
||||||
|
|
||||||
|
if (Stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Program.Invoke(Program.MainWindow, delegate
|
||||||
|
{
|
||||||
|
item.Command = cmd;
|
||||||
|
item.Enabled = canExecute;
|
||||||
|
});
|
||||||
|
hostMenuItems.Add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shuffle the list to make it look cool
|
||||||
|
// Helpers.ShuffleList(hostMenuItems);
|
||||||
|
|
||||||
|
// sort the hostMenuItems by star rating
|
||||||
|
hostMenuItems.Sort(new WlbHostStarCompare());
|
||||||
|
|
||||||
|
// refresh the drop-down-items from the menuItems.
|
||||||
|
foreach (VMOperationToolStripMenuSubItem menuItem in hostMenuItems)
|
||||||
|
{
|
||||||
|
if (Stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Program.Invoke(Program.MainWindow, delegate ()
|
||||||
|
{
|
||||||
|
menu.DropDownItems.Insert(hostMenuItems.IndexOf(menuItem) + 1, menuItem);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Program.Invoke(Program.MainWindow, () => menu.AddAdditionalMenuItems(selection));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EnableAppropriateHostsNoWlb(VMOperationToolStripMenuItem menu, Session session)
|
||||||
|
{
|
||||||
|
SelectedItemCollection selection = menu.Command.GetSelection();
|
||||||
|
IXenConnection connection = selection[0].Connection;
|
||||||
|
workerQueueWithoutWlb = new ProduceConsumerQueue(25);
|
||||||
|
VMOperationCommand cmdHome = new VMOperationHomeServerCommand(menu.Command.MainWindowCommandInterface, selection, menu._operation, session);
|
||||||
|
Host affinityHost = connection.Resolve(((VM)menu.Command.GetSelection()[0].XenObject).affinity);
|
||||||
|
|
||||||
|
if (Stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Program.Invoke(Program.MainWindow, delegate
|
||||||
|
{
|
||||||
|
var firstItem = (VMOperationToolStripMenuSubItem)menu.DropDownItems[0];
|
||||||
|
|
||||||
|
bool oldMigrateToHomeCmdCanRun = cmdHome.CanExecute();
|
||||||
|
if (affinityHost == null || menu._operation == vm_operations.start_on || oldMigrateToHomeCmdCanRun)
|
||||||
|
{
|
||||||
|
firstItem.Command = cmdHome;
|
||||||
|
firstItem.Enabled = oldMigrateToHomeCmdCanRun;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VMOperationCommand cpmCmdHome = new CrossPoolMigrateToHomeCommand(menu.Command.MainWindowCommandInterface, selection, affinityHost);
|
||||||
|
|
||||||
|
if (cpmCmdHome.CanExecute())
|
||||||
|
{
|
||||||
|
firstItem.Command = cpmCmdHome;
|
||||||
|
firstItem.Enabled = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
firstItem.Command = cmdHome;
|
||||||
|
firstItem.Enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
List<VMOperationToolStripMenuSubItem> dropDownItems = menu.DropDownItems.Cast<VMOperationToolStripMenuSubItem>().ToList();
|
||||||
|
|
||||||
|
if (Stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Adds the migrate wizard button, do this before the enable checks on the other items
|
||||||
|
Program.Invoke(Program.MainWindow, () => menu.AddAdditionalMenuItems(selection));
|
||||||
|
|
||||||
|
foreach (VMOperationToolStripMenuSubItem item in dropDownItems)
|
||||||
|
{
|
||||||
|
|
||||||
|
Host host = item.Tag as Host;
|
||||||
|
if (host != null)
|
||||||
|
{
|
||||||
|
// API calls could happen in CanExecute(), which take time to wait.
|
||||||
|
// So a Producer-Consumer-Queue with size 25 is used here to :
|
||||||
|
// 1. Make API calls for different menu items happen in parallel;
|
||||||
|
// 2. Limit the count of concurrent threads (now it's 25).
|
||||||
|
workerQueueWithoutWlb.EnqueueItem(() =>
|
||||||
|
{
|
||||||
|
VMOperationCommand cmd = new VMOperationHostCommand(menu.Command.MainWindowCommandInterface, selection, delegate { return host; }, host.Name().EscapeAmpersands(), menu._operation, session);
|
||||||
|
CrossPoolMigrateCommand cpmCmd = new CrossPoolMigrateCommand(menu.Command.MainWindowCommandInterface, selection, host, menu._resumeAfter);
|
||||||
|
|
||||||
|
VMOperationToolStripMenuSubItem tempItem = item;
|
||||||
|
bool oldMigrateCmdCanRun = cmd.CanExecute();
|
||||||
|
if ((menu._operation == vm_operations.start_on) || oldMigrateCmdCanRun)
|
||||||
|
{
|
||||||
|
if (Stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Program.Invoke(Program.MainWindow, delegate
|
||||||
|
{
|
||||||
|
tempItem.Command = cmd;
|
||||||
|
tempItem.Enabled = oldMigrateCmdCanRun;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool crossPoolMigrateCmdCanRun = cpmCmd.CanExecute();
|
||||||
|
if (crossPoolMigrateCmdCanRun || !string.IsNullOrEmpty(cpmCmd.CantExecuteReason))
|
||||||
|
{
|
||||||
|
if (Stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Program.Invoke(Program.MainWindow, delegate
|
||||||
|
{
|
||||||
|
tempItem.Command = cpmCmd;
|
||||||
|
tempItem.Enabled = crossPoolMigrateCmdCanRun;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Program.Invoke(Program.MainWindow, delegate
|
||||||
|
{
|
||||||
|
tempItem.Command = cmd;
|
||||||
|
tempItem.Enabled = oldMigrateCmdCanRun;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This class is an implementation of the 'IComparer' interface
|
||||||
|
/// for sorting vm placement menuItem List when wlb is enabled
|
||||||
|
/// </summary>
|
||||||
|
private class WlbHostStarCompare : IComparer<VMOperationToolStripMenuSubItem>
|
||||||
|
{
|
||||||
|
public int Compare(VMOperationToolStripMenuSubItem x, VMOperationToolStripMenuSubItem y)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
// if x and y are enabled, compare their start rating
|
||||||
|
if (x.Enabled && y.Enabled)
|
||||||
|
result = y.StarRating.CompareTo(x.StarRating);
|
||||||
|
|
||||||
|
// if x and y are disabled, they are equal
|
||||||
|
else if (!x.Enabled && !y.Enabled)
|
||||||
|
result = 0;
|
||||||
|
|
||||||
|
// if x is disabled, y is greater
|
||||||
|
else if (!x.Enabled)
|
||||||
|
result = 1;
|
||||||
|
|
||||||
|
// if y is disabled, x is greater
|
||||||
|
else if (!y.Enabled)
|
||||||
|
result = -1;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user