簡體   English   中英

WPF mvvm backgroundWorker busyIndi​​cator

[英]WPF mvvm backgroundWorker busyIndicator

我在與MVVM模式一起使用的程序中使用了busyIndi​​cator ,發現后台工作程序和處理綁定到視圖中的對象存在問題,因此我在所有功能上使用了Dispacher.Invoke方法使用綁定屬性,當我使用Dispacher之后,busyIndi​​cator出現了,但是當backgoundWorker完成視圖時,里面沒有任何元素,我在做什么錯?

我知道它的代碼有點低,但是我不知道有什么(如果有什么幫助),如有必要,請告訴我,我將用所需的代碼編輯此消息。

編輯:

以下代碼可能會有所幫助:

這是BW的創建,它發生在viewModel構造函數上

        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元素的部分

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));

                }                                 

            }
        }
    }
}

編輯:

這是從數據庫獲取數據的一部分:

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

調度程序在這里使用不正確

如果需要,可以使用Dispatcher以指定的優先級將代碼封送到UI線程上。 該代碼不會執行並立即返回,而是以根據DispatcherPriority順序指定的優先級運行。

基本上你的代碼在說

  • 建立清單
  • >>排隊代碼以稍后填充UI線程上的列表
  • 如果列表不為空,請執行一些代碼

該列表將始終為null,因為尚未運行填充它的代碼。 它只有在可用時才排隊運行一次。

正確的方法是在后台工作器上填充數據,然后將結果編組回UI線程以填充UI。

請注意,只能在創建對象的線程上修改對象。 因此,如果您打算稍后在UI中使用和/或修改某些對象,則應該看到類似以下內容:

  • 創建對象
  • 啟動BackgroundWorker以獲取數據
  • BackgroundWorker在不鎖定UI的情況下獲取后台線程上的數據
  • BackgroundWorker完成並使用Dispatcher在UI線程上運行代碼,該代碼將更新第一步中創建的對象並顯示結果

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM