首页 / 浏览问题 / 组件GIS / 问题详情
组件更换工作空间报错
216EXP 2019年08月22日

开发环境:SuperMap 9.1.1 idesktop dotnet

需求:在打开一个工作空间文件的情况下,实现不关闭组件窗体程序,切换到另外一个工作空间。

尝试了好几种方法,报各种各样的错误,测试情况如下:

情况1: workSpace.Close();程序直接关闭,程序报错

情况2:workSpace.Datasources.CloseAll();,只关闭数据源

情况3:workSpace.Dispose();报错,无法访问已经释放的对象

代码:

 /// <summary>
        /// 切换工作空间
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonXOk_Click(object sender, EventArgs e)
        {
            //1.切换工作空间
            bool openNewWs = false;
            if (workSpace.IsModified)
            {
                DialogResult dr = MessageBox.Show("工作空间已更改,是否保存?", "保存工作空间", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                if (dr == DialogResult.OK)
                {
                    bool isSaved = sceneControl.Scene.Workspace.Save();

                    if (workSpace.Scenes.Count > 0)
                    {
                        for (int i = 0; i < workSpace.Scenes.Count; i++)
                        {
                            workSpace.Scenes.SetSceneXML(workSpace.Scenes[i], sceneControl.Scene.ToXML());
                        }
                    }

                    bool success = workSpace.Save();
                    if (success)
                    {
                        MessageBox.Show("工作空间保存成功!", "提示");
                    }
                    else
                    {
                        MessageBox.Show("工作空间保存失败!", "提示");
                    }
                    //关闭所有数据源
                    workSpace.Datasources.CloseAll();
                    //先关闭工作空间
                    // workSpace.Close();
                    //TODO:无法访问已经释放的对象
                    // workSpace.Dispose();

                    //打开新场景
                    OpenWorkSpace(this.comboBoxExWSDS.Text.Trim());
                }
                else
                {
                    //关闭所有数据源
                    // workSpace.Datasources.CloseAll();
                    //先关闭工作空间
                    // workSpace.Close();
                    //TODO:无法访问已经释放的对象
                    workSpace.Dispose();
                    //打开新场景
                    OpenWorkSpace(this.comboBoxExWSDS.Text.Trim());
                }
            }
        }


        /// <summary>
        /// 打开工作空间
        /// </summary>
        /// <returns></returns>
        private void OpenWorkSpace(string workspaceName)
        {
            bool bOpen = false;
            string path = new DirectoryInfo("../../../../").FullName + @"Data\" + workspaceName + ".smwu";
            WorkspaceConnectionInfo wsConn = null;
            if (File.Exists(path))
            {
                wsConn = new WorkspaceConnectionInfo(path);
                wsConn.Type = WorkspaceType.SMWU;
            }
            else
            {
                //路径不存在的操作
                MessageBox.Show(path+"路径不存在名为" + workspaceName + "的工作空间!","提示");
            }

            if (wsConn != null)
            {
                // workSpace=new Workspace();
                bOpen = workSpace.Open(wsConn);
            }
            // return bOpen;
            if (bOpen)
            {
                MessageBox.Show("场景打开成功!", "提示");
            }
            else
            {
                MessageBox.Show("场景打开失败!", "提示");
            }
        }

请问,这种情况怎么处理呢??

1个回答

您好, workSpace.Close()方法在API文档中备注如下:

“工作空间关闭之前必需确保使用的该工作空间的地图都已经关闭或断开连接,否则会产生死机现象。”

所以请确认下是否有地图,场景等工作空间中用到的资源没有做关闭处理。
5,985EXP 2019年08月23日
没有地图,并且这样关闭的话容易损坏smwu文件
做一下如下尝试:

1.打开一个工作空间(打开后不要做任何操作)

2.点击一个按钮,关闭工作空间

3.再点击一个按钮,打开另一个工作空间

就这样一个小demo看是否有问题

看你上面的描述,工作空间都关闭不了了
我这边测试了没有问题哈,看看你是不是其它有地方还用着工作空间的资源没关闭或释放导致
你好,请问你是怎么测试的?先打开一个工作空间,然后关闭工作空间,最后再打开另外一个工作空间吗?
这3个步骤能够合并呢?能否把你测试的测试代码发到我的邮箱,我的邮箱是571716604@qq.com,谢谢

核心代码也很简单,如下:

namespace demotest
{
    public partial class Form1 : Form
    {


        SceneControl scenecontrol;
         Workspace workspace;
         MapControl mapcontrol;
         LayersControl layerscontrol;
         LayersTree layerstree;


        public Form1()
        {
            
            InitializeComponent();
            workspace = new Workspace();
            WorkspaceConnectionInfo info = new WorkspaceConnectionInfo(@"D:\zhanhui\iobject\supermap-iobjectsdotnet-9.1.0-16331-68391-all\SampleData\BeijingDEM\BeijingDEM.smwu");
            workspace.Open(info);
            mapcontrol = new MapControl();
            mapcontrol.Dock = DockStyle.Fill;
            panel1.Controls.Add(mapcontrol);
            mapcontrol.Map.Workspace = workspace;
            mapcontrol.Map.Open("BeijingTerrian@BeijingDEM2");


            mapcontrol.Map.MinScale = 1 / 629467.224916451;
            mapcontrol.Map.MaxScale = 1 / 54070.8228984002;
            mapcontrol.Map.Refresh();



                

          



          



        }
       
        private void button1_Click(object sender, EventArgs e)
        {
            mapcontrol.Map.Close();
            workspace.Close();
            

        }
        private void button2_Click(object sender, EventArgs e)
        {
            WorkspaceConnectionInfo info = new WorkspaceConnectionInfo(@"D:\zhanhui\iobject\supermap-iobjectsdotnet-9.1.0-16331-68391-all\SampleData\BeijingDEM\BeijingDEM.smwu");
            workspace.Open(info);
            mapcontrol.Map.Workspace = workspace;
            mapcontrol.Map.Open("BeijingTerrian@BeijingDEM2");


            mapcontrol.Map.MinScale = 1 / 629467.224916451;
            mapcontrol.Map.MaxScale = 1 / 54070.8228984002;
            mapcontrol.Map.Refresh();
        }
        



    }
}

...