QueuedTask.Run(..) hangs when I use Wait() method
public void SetFeatureLayerSymbolAsync(ArcGIS.Desktop.Mapping.FeatureLayer ftrLayer, CIMSymbol symbolToApply)
{
if (ftrLayer == null || symbolToApply == null)
throw new System.ArgumentNullException();
CIMSimpleRenderer currentRenderer = QueuedTask.Run(()=> ftrLayer.GetRenderer() as CIMSimpleRenderer).Result;
if (currentRenderer == null)
return;
symbolToApply.SetRealWorldUnits(ftrLayer.UsesRealWorldSymbolSizes);
currentRenderer.Symbol = symbolToApply.MakeSymbolReference();
QueuedTask.Run(()=> ftrLayer.SetRenderer(currentRenderer)).Wait();
}
And If I use await, it doesn't go to the next line(line 18), returns to the caller method(line 3) and QueuedTask still remains busy(line 4)
public void SetCustomPictureSymbol(ArcGIS.Desktop.Mapping.FeatureLayer featureLayer)
{
SetFeatureLayerSymbolAsync(featureLayer, _symbol.Symbol);
if (QueuedTask.Busy)
Task.Delay(1000);
}
public async Task SetFeatureLayerSymbolAsync(ArcGIS.Desktop.Mapping.FeatureLayer ftrLayer, CIMSymbol symbolToApply)
{
if (ftrLayer == null || symbolToApply == null)
throw new System.ArgumentNullException();
CIMSimpleRenderer currentRenderer = QueuedTask.Run(()=> ftrLayer.GetRenderer() as CIMSimpleRenderer).Result;
if (currentRenderer == null)
return;
symbolToApply.SetRealWorldUnits(ftrLayer.UsesRealWorldSymbolSizes);
currentRenderer.Symbol = symbolToApply.MakeSymbolReference();
await QueuedTask.Run(()=> ftrLayer.SetRenderer(currentRenderer));
if (QueuedTask.Busy)
{
Task.Delay(1000);
}
}
Why are you applying the Wait method? Your code is almost the same as in the documentation, but it wraps everything in the QueuedTask and doesn't include the Wait method.
public Task SetFeatureLayerSymbolAsync(FeatureLayer ftrLayer, CIMSymbol symbolToApply)
{
if (ftrLayer == null || symbolToApply == null)
throw new System.ArgumentNullException();
return QueuedTask.Run(() =>
{
//Get simple renderer from the feature layer
CIMSimpleRenderer currentRenderer = ftrLayer.GetRenderer() as CIMSimpleRenderer;
if (currentRenderer == null)
return;
//Set symbol's real world setting to be the same as that of the feature layer
symbolToApply.SetRealWorldUnits(ftrLayer.UsesRealWorldSymbolSizes);
//Update the symbol of the current simple renderer
currentRenderer.Symbol = symbolToApply.MakeSymbolReference();
//Update the feature layer renderer
ftrLayer.SetRenderer(currentRenderer);
});
}
Thank you for your Reply @KenBuja !
We want to do it for multiple layers. For single layer it works this way but for multiple it doesn't. For the second layer it gets QueuedTask busy when we try to Run it. To fix this we were trying Wait, await and other ways.
It fails in all cases.
Instead of using smaller QueuedTask calls everywhere, I've found that it's better to wrap the calls in a QueuedTask so everything executes in the same task. That would also allow you to remove the Async from SetFeatureLayerSymbol Something like:
public async Task ApplySymbologyAsync()
{
IEnumerable<FeatureLayer> featureLayers = ActiveMap.GetLayersAsFlattenedList().OfType<FeatureLayer>();
await QueuedTask.Run(() =>
{
foreach (FeatureLayer featureLayer in featureLayers)
{
SetFeatureLayerSymbol(featureLayer, {howeverYouObtainYourSymbol});
}
});
}
public void SetFeatureLayerSymbolAsync(ArcGIS.Desktop.Mapping.FeatureLayer ftrLayer, CIMSymbol symbolToApply)
{
if (ftrLayer == null || symbolToApply == null)
throw new System.ArgumentNullException();
CIMSimpleRenderer currentRenderer = ftrLayer.GetRenderer() as CIMSimpleRenderer;
if (currentRenderer == null)
return;
symbolToApply.SetRealWorldUnits(ftrLayer.UsesRealWorldSymbolSizes);
currentRenderer.Symbol = symbolToApply.MakeSymbolReference();
ftrLayer.SetRenderer(currentRenderer);
}