WPF mvvm backgroundWorker busyIndi​​cator [英] WPF mvvm backgroundWorker busyIndicator

查看:106
本文介绍了WPF mvvm backgroundWorker busyIndi​​cator的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在与之兼容的程序中使用 busyIndi​​cator MVVM模式,我发现后台工作程序和处理视图中绑定的对象存在问题,因此在使用Dispacher之后,我在所有使用绑定属性的函数上都使用了Dispacher.Invoke方法.向上,但是当backgoundWorker完成操作后,视图中没有任何元素时,我在做什么错了?

I'm using the busyIndicator in my program that works with MVVM pattern, I found out that there is a problem with background worker and dealing with objects that are binded in the view so I used the Dispacher.Invoke method on all of the functions that use binded properties, after I used the Dispacher the busyIndicator showed up, but when the backgoundWorker finished my view had no elements inside, what am I doing wrong?

我知道它的代码有点低,但是我不知道有什么(如果有什么帮助),如有必要,请告诉我,我将使用所需的代码来编辑此消息.

I know it's a little low in code but i didn't know what (and if) will help, if necessary please let me know and I'll edit this message with the desired code.

以下一些代码可能会有所帮助:

Here is some code that might help:

这是BW的创建,它发生在viewModel构造函数上

This is the creation of the BW, it happens on the viewModel constructor

        bw = new BackgroundWorker();
        bw.DoWork += new DoWorkEventHandler(bw_DoWork);
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
        bw.RunWorkerAsync(false);

这是BW功能

 void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        this.IsBusy = false;
    }

    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        this.BusyContent = "Please Wait...";
        this.IsBusy = true;
        ShowSystem((bool)e.Argument);
    }

showSystem方法很长,所以我只添加使用UI元素的部分

The method showSystem is very long so I'll add just the part that using UI elemnts

List<NodeViewModel> nodes = null;
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => nodes = new List<NodeViewModel>()));

int width = 0;
int height = 0;

foreach (var system in MainNet.Systems)
{
    Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => nodes.Add(CreateNode(system.Name, new Point(width, height), false, system.InputNum, system.OutputNum, system.Interfaces, system.Enums, system.Structs, update))));

    width += 150;
    if (width >= 700)
    {
        width = 0;
        height += 100;
    }
}

if (MainWindow.IsFlow)
{
    Object[] getInterfacesWithGuidToFlowParam = new Object[1];
    getInterfacesWithGuidToFlowParam[0] = MainWindow.GuidToFlow;

    interfacesForFlow = (List<String>)getInterfacesWithGuidToFlow.Invoke(sqlDB, getInterfacesWithGuidToFlowParam);

}

foreach (var system in MainNet.Systems)
{
    if (system.OutputNum > 0)       //this system has an output connector
    {
        int i = 0;
        foreach (var outId in system.Outputs)       //loop throw all systems ids that current system is connected to 
        {;
            ConnectionViewModel connection = null;
            Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => connection = new ConnectionViewModel()));

            Object[] getSystemNameParams = new Object[1];
            getSystemNameParams[0] = outId;
            string destSystemName = "";

            destSystemName = (String)getSystemName.Invoke(sqlDB, getSystemNameParams);

            NodeViewModel sourceItem = null;
            NodeViewModel destItem = null;
            Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => sourceItem = nodes.Find(x => x.Name == system.Name)));

            Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => destItem = nodes.Find(x => x.Name == destSystemName)));
            Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => destItem.InputSystems.Add(sourceItem.Name)));

            Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => sourceItem.OutputSystems.Add(destItem.Name)));

            Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => connection.SourceConnector = sourceItem.OutputConnectors[i++]));

            Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => connection.DestConnector = destItem.InputConnectors[destItem.InputConnectors.Count - 1]));

            // Add the connection to the view-model.
            //
            Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => connection.Type = ConnectionViewModel.ConnectorType.REGULAR));
            Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => this.Network.Connections.Add(connection)));

            if (MainWindow.IsFlow)
            {
                foreach (var @interface in interfacesForFlow)
                {
                    String[] systems = @interface.Split('_');
                    if(systems[0].Equals(sourceItem.Name) && systems[1].Equals(destItem.Name))
                        Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => connection.Type = ConnectionViewModel.ConnectorType.FLOW));

                }                                 

            }
        }
    }
}

这是从数据库获取数据的部分:

This is the part of getting the data from Database:

MainNet = Common.Model.Network.getNetwork();
        Debug.WriteLine("MainNet.Systems.Count = " + MainNet.Systems.Count);
        if (MainNet.Systems.Count == 0)
            update = true;
        List<String> systemNames = new List<string>();
        if (update)
        {
            if(MainNet.Systems.Count > 0)
                MainNet.Systems.Clear();
            if (this.Network.Nodes.Count > 0)
            {
                this.Network.Nodes.Clear();
                this.Network.Connections.Clear();
            }

            try
            {
                systemNames = (List<String>)getAllSystemMethod.Invoke(sqlDB, null);
                Debug.WriteLine("Success getAllSystemMethod");
            }
            catch (Exception ex)
            {
                logger.addMessage("Error in getAllSystemMethod: " + ex.Message + " Inner: " + ex.InnerException.Message);
                Debug.WriteLine("Error in getAllSystemMethod: " + ex.Message + " Inner: " + ex.InnerException.Message);
            }

            #region CreateSystems
            foreach (var sysName in systemNames)
            {
                #region Intializating
                ObservableCollection<Common.Model.Enum> enums = new ObservableCollection<Common.Model.Enum>();
                ObservableCollection<Common.Model.Struct> structs = new ObservableCollection<Common.Model.Struct>();
                ObservableCollection<Common.Model.Interface> interfaces = new ObservableCollection<Common.Model.Interface>();
                //List<Model.Enum> enums = new List<Model.Enum>();
                //List<Model.Struct> structs = new List<Model.Struct>();
                //List<Model.Interface> interfaces = new List<Model.Interface>();

                int systemId = -1;
                Object[] getSystemIdParams = new Object[1];
                getSystemIdParams[0] = sysName;
                try
                {
                    systemId = (int)getSystemId.Invoke(sqlDB, getSystemIdParams);
                    Debug.WriteLine("Success getSystemId systemId = " + systemId);
                }
                catch (Exception ex)
                {
                    logger.addMessage("Error in getSystemId: " + ex.Message + " Inner: " + ex.InnerException.Message);
                    Debug.WriteLine("Error in getSystemId: " + ex.Message + " Inner: " + ex.InnerException.Message);
                }

                List<int> sysEnumsIds = new List<int>();
                List<int> sysStructsIds = new List<int>();
                List<int> sysInterfacesIds = new List<int>();

                Object[] getSysEnumsIdParams = new Object[1];
                getSysEnumsIdParams[0] = systemId;
                try
                {
                    sysEnumsIds = (List<int>)getSysEnumsId.Invoke(sqlDB, getSysEnumsIdParams);      //return List<int> all system Enums ids
                    if (sysEnumsIds.Count > 0)
                        Debug.WriteLine("Success getSysEnumsId first count is " + sysEnumsIds.Count);
                    else
                        Debug.WriteLine("success getSysEnumsId but no ids found");
                }
                catch (Exception ex)
                {
                    logger.addMessage("Error in getSysEnumsId: " + ex.Message + " Inner: " + ex.InnerException.Message);
                    Debug.WriteLine("Error in getSysEnumsId: " + ex.Message + " Inner: " + ex.InnerException.Message);
                }


                Object[] getSysStructsIdParams = new Object[1];
                getSysStructsIdParams[0] = systemId;
                try
                {
                    sysStructsIds = (List<int>)getSysStructsId.Invoke(sqlDB, getSysStructsIdParams);
                    if (sysStructsIds.Count > 0)
                        Debug.WriteLine("success getSysStructsId count = " + sysStructsIds.Count);
                    else
                        Debug.WriteLine("success getSysStructsId but no ids found");
                }
                catch (Exception ex)
                {
                    logger.addMessage("Error in getSysStructsId: " + ex.Message + " Inner: " + ex.InnerException.Message);
                    Debug.WriteLine("Error in getSysStructsId: " + ex.Message + " Inner: " + ex.InnerException.Message);
                }


                Object[] getSysInterfacesIdParams = new Object[1];
                getSysInterfacesIdParams[0] = systemId;
                try
                {
                    sysInterfacesIds = (List<int>)getSysInterfacesId.Invoke(sqlDB, getSysInterfacesIdParams);
                    if (sysInterfacesIds.Count > 0)
                        Debug.WriteLine("Success getSysInterfacesId count = " + sysInterfacesIds.Count);
                    else
                        Debug.WriteLine("success getSysInterfacesId but no ids found");
                }
                catch (Exception ex)
                {
                    logger.addMessage("Error in getSysInterfacesId: " + ex.Message + " Inner: " + ex.InnerException.Message);
                    Debug.WriteLine("Error in getSysInterfacesId: " + ex.Message + " Inner: " + ex.InnerException.Message);
                }
                #endregion

                    Object[] getStructFromIdParam = new Object[1];
                    getStructFromIdParam[0] = @struct;
                    List<Object> tempStruct = new List<object>();
                    try
                    {

                        tempStruct = (List<Object>)getStructFromId.Invoke(sqlDB, getStructFromIdParam);

                        Debug.WriteLine("Success getStructFromId " + tempStruct.Count);
                    }
                    catch (Exception ex)
                    {
                        logger.addMessage("Error in getStructFromIdParam : " + ex.Message + " Inner: " + ex.InnerException.Message);
                        Debug.WriteLine("Error in getStructFromIdParam : " + ex.Message + " Inner: " + ex.InnerException.Message);
                    }
                    structs.Add(new Common.Model.Struct(Convert.ToString(tempStruct[0]), Convert.ToString(tempStruct[1]), Convert.ToString(tempStruct[2]), fields, bitFields));
                    Debug.WriteLine("Success adding new struct: " + structs.Last().Name);






                }
                #endregion

                #region GetInterfaces
                foreach (var @interface in sysInterfacesIds)        //get interface
                {

                    ObservableCollection<Common.Model.Message> messages = new ObservableCollection<Common.Model.Message>();
                    ObservableCollection<Common.Model.Definition> definitions = new ObservableCollection<Common.Model.Definition>();
                    ObservableCollection<Common.Model.Include> includes = new ObservableCollection<Common.Model.Include>();

                    List<int> includesIds = new List<int>();
                    List<int> definitionsIds = new List<int>();
                    List<int> messagesIds = new List<int>();


                    #region getIncludes
                    Object[] getIncludesIdsParams = new object[1];
                    getIncludesIdsParams[0] = @interface;
                    try
                    {
                        includesIds = (List<int>)getIncludesIds.Invoke(sqlDB, getIncludesIdsParams);
                        Debug.WriteLine("Success getIncludesIds " + includesIds.Count);
                    }
                    catch (Exception ex)
                    {
                        logger.addMessage("Error in getIncludesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
                        Debug.WriteLine("Error in getIncludesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
                    }

                    foreach (var id in includesIds)
                    {
                        Object[] getIncludeParams = new object[1];
                        getIncludeParams[0] = id;
                        string includeName = "";
                        try
                        {
                            includeName = (string)getInclude.Invoke(sqlDB, getIncludeParams);
                            Debug.WriteLine("Success get include name = " + includeName);
                        }
                        catch (Exception ex)
                        {
                            logger.addMessage("Error in getInclude " + ex.Message + " Inner: " + ex.InnerException.Message);
                            Debug.WriteLine("Error in getInclude " + ex.Message + " Inner: " + ex.InnerException.Message);
                        }
                        includes.Add(new Common.Model.Include(includeName));
                    }
                    #endregion

                    #region getdefinitions
                    Object[] getdefinitionsIdsParams = new object[1];
                    getdefinitionsIdsParams[0] = @interface;
                    try
                    {
                        definitionsIds = (List<int>)getDefinitionsIds.Invoke(sqlDB, getdefinitionsIdsParams);
                        Debug.WriteLine("Success getDefinitionsIds " + definitionsIds.Count);
                    }
                    catch (Exception ex)
                    {
                        logger.addMessage("Error in getDefinitionsIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
                        Debug.WriteLine("Error in getDefinitionsIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
                    }

                    foreach (var id in definitionsIds)
                    {
                        List<Object> definition = new List<object>();

                        Object[] getDefinitionParams = new object[1];
                        getDefinitionParams[0] = id;
                        string includeName = "";
                        try
                        {
                            definition = (List<Object>)getDefinition.Invoke(sqlDB, getDefinitionParams);
                            Debug.WriteLine("Success getDefinisions " + definition[0]);
                        }
                        catch (Exception ex)
                        {
                            logger.addMessage("Error in getInclude " + ex.Message + " Inner: " + ex.InnerException.Message);
                            Debug.WriteLine("Error in getInclude " + ex.Message + " Inner: " + ex.InnerException.Message);
                        }

                        definitions.Add(new Common.Model.Definition(Convert.ToString(definition[0]), Convert.ToInt32(definition[1])));

                    }
                    #endregion

                    #region getMessages
                    Object[] getMessagesIdsParams = new object[1];
                    getMessagesIdsParams[0] = @interface;
                    Debug.WriteLine("Trying to get messages for interface #" + @interface);
                    try
                    {
                        messagesIds = (List<int>)getMessagesIds.Invoke(sqlDB, getMessagesIdsParams);
                        Debug.WriteLine("Success getMessagesIds " + messagesIds.Count);
                    }
                    catch (Exception ex)
                    {
                        logger.addMessage("Error in getMessagesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
                        Debug.WriteLine("Error in getMessagesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
                    }

                    foreach (var id in messagesIds)
                    {
                        //List<Model.MType> types = new List<Model.MType>();
                        ObservableCollection<Common.Model.MType> types = new ObservableCollection<Common.Model.MType>();
                        List<int> typesIds = new List<int>();

                        Object[] getMessageTypesIdsParams = new Object[1];
                        getMessageTypesIdsParams[0] = id;
                        try
                        {
                            typesIds = (List<int>)getMessageTypesIds.Invoke(sqlDB, getMessageTypesIdsParams);
                            Debug.WriteLine("Success getMessageTypesIds " + typesIds.Count);
                        }
                        catch (Exception ex)
                        {
                            logger.addMessage("Error in getMessageTypesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
                            Debug.WriteLine("Error in getMessageTypesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
                        }
                        foreach (var typeId in typesIds)
                        {
                            List<Object> type = new List<object>();

                            Object[] getTypeParams = new object[1];
                            getTypeParams[0] = typeId;
                            //string includeName = "";
                            try
                            {
                                type = (List<Object>)getType.Invoke(sqlDB, getTypeParams);
                                Debug.WriteLine("Success getType");
                            }
                            catch (Exception ex)
                            {
                                logger.addMessage("Error in getType " + ex.Message + " Inner: " + ex.InnerException.Message);
                                Debug.WriteLine("Error in getType " + ex.Message + " Inner: " + ex.InnerException.Message);
                            }

                            types.Add(new Common.Model.MType((string)type[0], (string)type[1], (string)type[2], (string)type[3], (string)type[4], (string)type[5], (Guid)type[6]));
                            Debug.WriteLine("Success adding new type: " + (string)type[0] + " " + (string)type[1] + " " + (string)type[2] + " " + (string)type[3] + " " + (string)type[4] + " " + (string)type[5] + " " + (Guid)type[6]);
                        }

                        string sourceSystem = "";
                        string destSystem = "";


                        List<Object> message = new List<object>();
                        Object[] getMessageParams = new Object[1];
                        getMessageParams[0] = id;
                        try
                        {
                            message = (List<Object>)getMessage.Invoke(sqlDB, getMessageParams);
                            Debug.WriteLine("Success getMessageParams");

                        }
                        catch (Exception ex)
                        {
                            logger.addMessage("Error in getMessageTypesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
                            Debug.WriteLine("Error in getMessageTypesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
                        }

                        messages.Add(new Common.Model.Message(types, message[0].ToString(), (int)message[1], message[2].ToString(), message[3].ToString(), message[4].ToString(), message[5].ToString(), message[6].ToString(), message[7].ToString(), message[8].ToString(), message[9].ToString()));
                        Debug.WriteLine("Success adding new Message: " + message[0].ToString() + " " + (int)message[1] + " " + message[2].ToString() + " " + message[3].ToString() + " " + message[4].ToString() + " " + message[5].ToString() + " " + message[6].ToString() + " " + message[7].ToString() + " " + message[8].ToString() + " " + message[9].ToString());

                    }
                    #endregion


                    Object[] getInterfaceFromIdParam = new Object[1];
                    getInterfaceFromIdParam[0] = @interface;
                    List<Object> tempInterface = new List<object>();
                    try
                    {

                        tempInterface = (List<Object>)getInterfaceFromId.Invoke(sqlDB, getInterfaceFromIdParam);

                        Debug.WriteLine("Success getInterfaceFromId " + tempInterface.Count);
                    }
                    catch (Exception ex)
                    {
                        logger.addMessage("Error in getInterfaceFromId : " + ex.Message + " Inner: " + ex.InnerException.Message);
                        Debug.WriteLine("Error in getInterfaceFromId : " + ex.Message + " Inner: " + ex.InnerException.Message);
                    }
                    interfaces.Add(new Common.Model.Interface(messages, definitions, includes, Convert.ToString(tempInterface[0]), Convert.ToString(tempInterface[1]), Convert.ToInt32(tempInterface[2]), Convert.ToInt32(tempInterface[3]), Convert.ToBoolean(tempInterface[4])));
                    Debug.WriteLine("Success adding new interface: " + interfaces.Last().Name);

                }

                #endregion

                #region InputOutputNumber
                List<int> inputs = new List<int>();
                List<int> outputs = new List<int>();

                int inputCount = 0;
                int outputCount = 0;

                Object[] getSysInputNumParams = new Object[1];
                getSysInputNumParams[0] = systemId;
                try
                {
                    inputs = (List<int>)getSysInputs.Invoke(sqlDB, getSysInputNumParams);
                    if (inputs != null)
                    {
                        inputCount = inputs.Count;
                        Debug.WriteLine("Success getSysInputNum inputs = " + inputCount);
                    }
                    else
                        Debug.WriteLine("Success getSysInputNum inputs = 0");
                }
                catch (Exception ex)
                {
                    logger.addMessage("Error in getSysInputNum: " + ex.Message + " Inner: " + ex.InnerException.Message);
                    Debug.WriteLine("Error in getSysInputNum: " + ex.Message + " Inner: " + ex.InnerException.Message);
                }


                Object[] getSysOutputNumParams = new Object[1];
                getSysOutputNumParams[0] = systemId;
                try
                {
                    outputs = (List<int>)getSysOutputs.Invoke(sqlDB, getSysOutputNumParams);
                    if (outputs != null)
                    {
                        outputCount = outputs.Count;
                        Debug.WriteLine("Success getSysOutputNum outputs = " + outputCount);
                    }
                    else
                        Debug.WriteLine("Success getSysOutputNum outputs = 0");
                }
                catch (Exception ex)
                {
                    logger.addMessage("Error in getSysOutputNum: " + ex.Message + " Inner: " + ex.InnerException.Message);
                    Debug.WriteLine("Error in getSysOutputNum: " + ex.Message + " Inner: " + ex.InnerException.Message);
                }
                #endregion

                Common.Model.System system = null;
                try
                {
                    system = new Common.Model.System(interfaces, enums, structs, sysName, inputCount, outputCount, inputs, outputs);
                    Debug.WriteLine("Success adding new system");
                }
                catch (Exception ex)
                {
                    logger.addMessage("Error in creating new system: " + ex.Message);
                    Debug.WriteLine("Error in creating new system: " + ex.Message);
                }
                MainNet.Systems.Add(system);
                Debug.WriteLine("Done! you now have a new system with: " + interfaces.Count + " interfaces And " + enums.Count + " Enums and " + structs.Count + " Structs, The name is: " + sysName + " numOfInput: " + inputCount + " numOfOutput: " + outputCount);
            #endregion


            }
        #endregion

推荐答案

此处未正确使用调度程序

The dispatcher is being used incorrectly here

可以使用Dispatcher将代码封送到UI线程上,如果需要,可以指定优先级.该代码不会执行并立即返回,而是会根据

The Dispatcher can be used to marshal code onto the UI thread, at a specified priority if desired. The code does not get executed and return immediately, but instead gets run at the priority specified according to the DispatcherPriority order.

基本上,您的代码在说

  • 创建列表
  • >>队列代码,以便稍后在UI线程中填充列表
  • 如果列表不为空,请执行一些代码

该列表将始终为null,因为尚未运行填充该列表的代码.它只有在可用时才排队运行一次.

The list will always be null because the code to populate it hasn't been run yet. Its only been queued to run once when available.

执行此操作的正确方法是将数据填充到后台工作程序中,然后将结果编组回UI线程以填充UI.

The correct way to do this would be to populate your data on the background worker, and then marshal the results back onto the UI thread to populate your UI.

请注意,只能在创建对象的线程上修改对象.因此,如果您打算稍后在UI中使用和/或修改某些对象,您应该会看到类似以下内容:

Note that objects can only be modified on the thread at which they were created on. So if you have some objects you plan on using and/or modifying from the UI later on, you should see something like this:

  • 创建对象
  • 启动BackgroundWorker获取数据
  • BackgroundWorker无需锁定UI即可在后台线程上获取数据
  • BackgroundWorker完成并使用Dispatcher在UI线程上运行代码,这些代码将更新第一步中创建的对象并显示结果

这篇关于WPF mvvm backgroundWorker busyIndi​​cator的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆