Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

What I am doing: I am trying to run a geoprocessor tool in a background thread other than UI thread. I am passing string path of arcObjects and creating that arcObject in my background thread. Then I am passing those arcObjects to geoProcessor tool.

In UI thread, Button's on click method:

private void btnFindInterction_Click(object sender, EventArgs e)
{
    List<IFeatureLayer> layers = GetAllMapFeatureLayers();

    string featureLayerPath1 = GetFeatureLayerPath(layers[0]);
    string featureLayerPath2 = GetFeatureLayerPath(layers[1]);

    Thread worker = new Thread(new ThreadStart(() =>
        {
            IFeatureClass featureClass1 = GetFeatureClassFromPath(featureLayerPath1);
            IFeatureClass featureClass2 = GetFeatureClassFromPath(featureLayerPath2);

            var result = RunIntersectTool(featureClass1, featureClass2);
            OnCalculationComplete(intersectedFeatureClasssPath);
        }
    ));

    worker.SetApartmentState(ApartmentState.STA);
    worker.Start();
}

The RunIntersectTool method:

string RunIntersectTool(IFeatureClass featureClass1, IFeatureClass featureClass2)
{
    IWorkspace workspace = GetTempGDBWorkspace();
    string intersectFeatureClassName = "Intersect_result";
    string intersectFeatureClassPath = workspace.PathName + "\\" + intersectFeatureClassName;
    try
    {
        var gp = new Geoprocessor { OverwriteOutput = true, AddOutputsToMap = false };
        IGpValueTableObject gpValueTableObject = new GpValueTableObjectClass();
        gpValueTableObject.SetColumns(1);
        var inFeature1 = imperviousFeatureClass as object;
        gpValueTableObject.AddRow(inFeature1);
        var inFeature2 = watershedFeatureClass as object;
        gpValueTableObject.AddRow(inFeature2);

        var intersectTool = new Intersect
        {
            in_features = gpValueTableObject,
            out_feature_class = intersectFeatureClassPath 
        };
        gp.Execute(intersectTool, null);
        return intersectFeatureClassPath;
    }
    catch (Exception e)
    {
        return null;
    }
}

What problem am I facing: The tool runs perfectly in some machines, but gives error in some machine: "000732 : : Dataset does not exist or is not supported" And this error never happen if I don't use threading. I read help files of Running a geoprocessing tool using background geoprocessing, but I couldn't find anything that says I can't pass arcObjects.

There is another problem I am facing. Whenever I ran the tool, it works fine first time(in some machines), but gives error when it creates an instance of geoprocessor at second time. Error message: "Attempted to read or write protected memory". I guess this error is also related to multithreading and arcObjects.

share|improve this question
    
Both featurelayer paths are derived from layers[0], is that a typo? –  Kirk Kuykendall Jul 22 '13 at 13:12
    
@KirkKuykendall: Oh really sorry. It's a typing mistake. But my actual code, I get my layer different way and two layers are always different two layers –  Emi Jul 23 '13 at 6:47
    
In GetFeatureclassFromPath, are you using Activator.CreateInstance to open the workspace? –  Kirk Kuykendall Jul 23 '13 at 13:51
1  
Right, but just be sure to use Activator.CreateInstance instead of new. –  Kirk Kuykendall Jul 24 '13 at 12:55
1  
Something to do with the "threads in isolation". Usually a singleton means one instance of the class per process. Using CreateInstance somehow (not sure how) allows a singleton to be one instance of the class per thread, eliminating a lot of the marshalling issues. Did switching to Activator resolve the issue? –  Kirk Kuykendall Jul 29 '13 at 15:44

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.