Comments (8)
Hi, i wonder wouldn't it be better idea to abort whole thread upon cancellation request. That approach will spare too much cancellation checks in the logic.
from graphx.
Aborting a thread is unsafe. (http://stackoverflow.com/a/5299124) It might be quick and easy, but it is something you want to do only in exceptional cases.
from graphx.
Without having looked at the code in question, I'd suggest using a ManualResetEventSlim as it's rather fast, and does not require slow kernel objects.
from graphx.
I think I'll have a go at it this evening, and do some measurements on it. Don't want to slow down the layout code needlessly!
from graphx.
I've almost forgot about this task, that is also an option to implement :)
from graphx.
I've been looking at a solution for this issue, but I need to confirm with you first, so that I don't step onto future plans of yours.
If I understand the code correctly, all algorithm implementations are fully sequential (no method spawns a new thread/task/worker). The launch of each algorithm however (GraphArea<TVertex, TEdge, TGraph>._relayoutGraphMain(bool, bool)
) may be done concurrently in a background worker if requested.
AlgorithmBase
seems to have been designed to support cancellation (see AlgorithmBase.Abort()
). Despite the support for cancellation, I can only find one concrete implementation FRLayoutAlgorithm
that supports cancellation. Is this design part of a long term goal?
I've been toying with the idea of using a volatile bool
wrapped inside an object. The object, implements the fictitious interface:
interface IAlgorithmControl {
void ThrowIfAborted { get; }
}
A concrete implementation of this interface would look like:
class AlgorithmControl : IAlgorithmControl {
private volatile bool _abortRequested;
public void RequestAbort() {
_abortRequested = true;
}
public void ThrowIfAborted() {
if(_abortRequested)
throw new OperationCanceledException();
}
}
An instance of this concrete class is then passed to each Compute()
method as an argument. Each implementation may periodically call ThrowIfAborted()
. Typically it is instantiated in GraphArea<TVertex, TEdge, TGraph>._relayoutGraphMain(bool, bool)
like this:
...
Worker.DoWork += ((sender, e) =>
{
try
{
_algorithmControl = new AlgorithmControl();
_relayoutGraph(_algorithmControl);
}
catch (OperationCanceledException)
{
// Possibly do some clean up
}
};
...
In CancelRelayout()
:
public void CancelRelayout()
{
if(_algorithmControl != null)
_algorithmControl.RequestAbort();
}
We also need to join the background worker upon termination, because there are race conditions lurking here. Even though a background worker has been requested to terminate, it will still keep on modifying the graph, and odds are that another worker is executing at the same time. The actual changes to the graph is serialized by the UI thread, but that will only make the concurrent changes coarse.
I think this would be the most efficient way to cancel a background layout worker. Why not use the cancellation mechanism in place with the background worker you might ask? Well, I did consider it, but I changed my mind when I looked at the implementation of the cancellation (http://referencesource.microsoft.com/#System/compmod/system/componentmodel/BackgroundWorker.cs). The implementation uses a non-volatile bool as a flag for determining whether a cancellation is in progress or not. I'm not sure, but it does not seem right as the compiler and JIT may generate code that prevents the background worker to detect a change from false
to true
in a timely fashion. I am by no means an expert on the subject, so I might just be paranoid here. I do know though that the use of a volatile bool is OK, because the value never fluctuates it stays false until someone sets it to true. It can't go from false
to true
to false
. No locks are used, nor are any expensive kernel objects used, so I think it's the most correct and performant way to signal a cancellation. A bonus point is that the solution is PCL compliant, so it will work for store apps as well.
So to sum it up: I'd like to remove the Abort()
from AlgorithmBase
, and extend all algorithm interfaces with a Compute(IAlgorithmControl control)
method. The default implementation non-abortable version will be left, but will default to a call to the new method, but with a "dummy object" that never throws. Would this totally mutilate GraphX, or is it worth a shot?
from graphx.
Hi, i'm not sure i understand all of this entirely :)
- Overall idea is fine as i can see.
- Throwing an exception will be more fastest solution by now but honestly i'm not sure about the quality. It is better to make _abortRequested public readonly property and check it, If it is true then return all the way up from the calculation. But for now we can see how it goes with an exception throwing and clean up any junk calculations after the abort.
- Take a look at https://msdn.microsoft.com/en-us/library/system.threading.cancellationtoken(v=vs.110).aspx it is similar to that you propose as i can see :) I'm not sure it's PCL compliant sp any PCL compliant solution will be better.
- All abort logic in algorithms are obsolete and can be freely refactored.
from graphx.
Thanks for mentioning cancellation tokens. I had just assumed they are not available for PCL assemblies. I just saw that Task is available in for PCL, which means that cancellation token (and source) is too. Awesome! Scratch all I said. The concurrency should the IMO be executed as a task with cancellation-support. I'll give it a go tonight!
from graphx.
Related Issues (20)
- The sample application not building
- [MVVM] Vertices text is not showing up correctly HOT 2
- Background Image of Vertex HOT 3
- How to remove label edge? HOT 2
- How to remove minimap of the view finder?
- How to export graph to png?
- Slow Drag Vertex
- Implementation of the mvvm model with GraphX
- Initialization error on pass false to tracePositionChange of VertexControl Constructor
- Graph virtualization
- is it possible to add new verticies/edges without having a full relayout of the graph?
- How to make arrows?
- How to make edges doesn't cross HOT 3
- How to add double click event to a vertex HOT 2
- How to change the type of edges?
- Release nuget version with support for QuikGraph HOT 1
- recent development HOT 1
- strange behavior HOT 2
- Edges with same source and target rendered as a star instead of an edge? HOT 1
- the additional api website is currently unavailable
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from graphx.