НЕТ операционной системы позволяет изменять пользовательский интерфейс из другого потока.В вашем случае, хотя вы не пытаетесь обновить пользовательский интерфейс в фоновом режиме, вы собираете график в фоновом режиме и задаете свойство.Там нет работы интерфейса здесь.Если элемент рендеринга связывается с этим свойством, он получит уведомление, прочитает свойство и сам обновится, все в потоке пользовательского интерфейса.
Хотя код нуждается в улучшении.Задачи не являются потоками, и нет причин использовать холодные задачи и тому подобное.Start()
не гарантирует, когда задача будет запущена.Задача все равно будет запланирована для выполнения в потоке потоков и, возможно, будет ждать, если там нет доступных потоков.
Код можно упростить до следующего:
var graph = await Task.Run(()=> {
var g = new BidirectionalGraph<object, IEdge<object>>();
foreach (MyItem p in _myItemList)
{
g.AddVertex(p);
}
foreach (MyItem p in _myItemList)
{
foreach (MyItem n in p.CallingList)
{
g.AddEdge(new Edge<object>(p, n));
}
}
return g;
};
_graph = graph;
OnPropertyChanged("Graph");
A Лучше Идея состоит в том, чтобы использовать правильное свойство вместо изменения полей и создания события:
public BidirectionalGraph Graph
{
get => _graph;
set
{
_graph=value;
OnPropertyChanged(nameof(Graph));
}
}
...
public async Task MyGraphMethod()
{
Graph=graph;
}
ОБНОВЛЕНИЕ
real вопрос, похоже, почему GraphLayout занимает так много времени для отображения графика?
Установите для свойства AsyncCompute
GraphLayout значение true:
<graphsharp:GraphLayout
Graph="{Binding ElementName=root, Path=Graph}"
LayoutAlgorithmType="LinLog"
OverlapRemovalAlgorithmType="FSA"
HighlightAlgorithmType="Simple"
AsyncCompute = "true" />
GraphSharp былзаброшен 6 лет назад если не больше.Сам Codeplex отключился, и теперь единственным доступным исходным кодом является либо архивированный исходный код, либо вилки на Github, например этот .
Примеры в этом репо-шоуесть свойство AsyncCompute
, которое будет запускать алгоритмы макета в фоновом режиме:
<sample:MyGraphLayout x:Name="Layout" LayoutAlgorithmType="ISOM" OverlapRemovalAlgorithmType="FSA" Graph="{Binding}"
AsyncCompute="true" ShowAllStates="false" HighlightAlgorithmType="Simple">
<sample:MyGraphLayout.LayoutParameters>
<isom:ISOMLayoutParameters Width="1200" Height="1200" />
</sample:MyGraphLayout.LayoutParameters>
</sample:MyGraphLayout>
Когда AsyncCompute имеет значение true, метод элемента управления *1040* использует BackgroundWorker для выполненияоперация в фоновом режиме
Это свойство существует и в исходном архиве исходных проектов.