6 Replies - 750 Views - Last Post: 22 December 2011 - 01:00 PM

#1 Amrykid  Icon User is offline

  • 4+1=Moo
  • member icon

Reputation: 148
  • View blog
  • Posts: 1,589
  • Joined: 16-December 08

Project Carbon

Posted 22 December 2011 - 10:56 AM

Project Carbon is a .NET library written in C#. It's purpose is to make general (although, slightly more advanced) task easier and simpler. At the time of posting, I only have completed one of the features and that is 'RuntimeOperations'.

The name is a bit misleading but RuntimeOperations can be considered a higher level wrapper over threads but is more of a way of executing calculations or functions that be paused and continued.

This works by executing your code in cycles and each cycle returns a state, which is passed to the next cycle of your code and so on. Take a look at the VB.NET example below. It is perofmring the Collatz Conjecture on 27:
Imports Carbon.Operations
Public Class Program

    Public Shared Sub Main()
        Dim oper = RuntimeOperationsHelper.CreateOperation(
            Sub(handler As Carbon.Operations.RuntimeOperationHandle(Of BasicRuntimeOperationState), state As BasicRuntimeOperationState)
                'During every cycle, this body of code is called.

                System.Threading.Thread.Sleep(1000) 'Simulate delay to showcase pausing and continuing
                If state.Value = 1 Then 'Check the previous state and if its equal to 1.
                    handler.Return(
                        RuntimeOperationsHelper.CreateBasicStateFromValue(1)) 'If its equal to one. Stop the operation as successful and return 1
                Else
                    If state.Value Mod 2 = 0 Then
                        handler.Pass(
                            RuntimeOperationsHelper.CreateBasicStateFromValue(
                                state.Value / 2)) 'If the previous state is divisible by 2, divide it by 2 and pass it to the next cycle.
                    Else
                        handler.Pass(
                            RuntimeOperationsHelper.CreateBasicStateFromValue(
                                state.Value * 3 + 1)) 'Otherwise, multiple by 3 and add 1 to the previous state, then pass it to the next cycle.
                    End If
                End If

            End Sub,
    "Performing the collatz conjecture..")



        Console.WriteLine("Running operation test..")
        oper.Start(
            RuntimeOperationsHelper.CreateBasicStateFromValue(27)) 'Start the operation

        ''Below simulates a test by waiting on the operation and pausing and continuing to simulate usage.
        Dim i = 0
        While (True)
            System.Threading.Thread.Sleep(10)
            i += 1
            If i = 5 Then
                oper.Pause()
                Console.WriteLine("Operation paused...")
                System.Threading.Thread.Sleep(3000)
            ElseIf i = 10 Then
                oper.Continue()
                Console.WriteLine("Operation continued...")
            ElseIf i = 50 Then
                Return 'Exit
            End If

        End While
    End Sub

End Class




Theres more features where that come from, like a simplied MVVM-based model and also extended wrappers around System.Threading.Tasks.Task.

You can find the source code on Github and/or you can wait for the NuGet package.

If you do build it, let me know if you have any suggestions or questions.

This post has been edited by Amrykid: 22 December 2011 - 11:00 AM


Is This A Good Question/Topic? 2
  • +

Replies To: Project Carbon

#2 janne_panne  Icon User is offline

  • WinRT Dev
  • member icon

Reputation: 429
  • View blog
  • Posts: 1,047
  • Joined: 09-June 09

Re: Project Carbon

Posted 22 December 2011 - 11:40 AM

Couple of questions came into my mind while checking the source code:

Why are you forcing the type parameter of RuntimeOperation to be RuntimeOperationState while RuntimeOperationState doesn't do anything? If the user wants to pass in his class called Customers, why it has to derive from RuntimeOperationState? It could be justified if the class actually had something crucial inside of it but at the moment it's empty.

Why is the constructor of RuntimeOperation internal? Would it hurt the logic of the class to give user a chance to make instantiate the class? I think internal constructor and public static creation method is mostly used when the initializing might be quite complicated for the user or contains some logic which the user doesn't have access to for some reasons. You could have both the public constuctor and the static creation method in your case, in my opinion.

I would also move the Create method from RuntimeOperationhelper<T> class inside RuntimeOperation class. I think that would be more logical place for such method, not everything has to be inside a class called Helper when it can be inside the class it's helping.

Those things came into my mind and I think you should consider them. Of course they might have a reason, like unit testing or some features that will come later.

Those things aside, it looks nice :) If I ever need a library like that, I will download it.
Was This Post Helpful? 1
  • +
  • -

#3 Amrykid  Icon User is offline

  • 4+1=Moo
  • member icon

Reputation: 148
  • View blog
  • Posts: 1,589
  • Joined: 16-December 08

Re: Project Carbon

Posted 22 December 2011 - 11:48 AM

View Postjanne_panne, on 22 December 2011 - 01:40 PM, said:

Couple of questions came into my mind while checking the source code:

Why are you forcing the type parameter of RuntimeOperation to be RuntimeOperationState while RuntimeOperationState doesn't do anything? If the user wants to pass in his class called Customers, why it has to derive from RuntimeOperationState? It could be justified if the class actually had something crucial inside of it but at the moment it's empty.

Why is the constructor of RuntimeOperation internal? Would it hurt the logic of the class to give user a chance to make instantiate the class? I think internal constructor and public static creation method is mostly used when the initializing might be quite complicated for the user or contains some logic which the user doesn't have access to for some reasons. You could have both the public constuctor and the static creation method in your case, in my opinion.

I would also move the Create method from RuntimeOperationhelper<T> class inside RuntimeOperation class. I think that would be more logical place for such method, not everything has to be inside a class called Helper when it can be inside the class it's helping.

Those things came into my mind and I think you should consider them. Of course they might have a reason, like unit testing or some features that will come later.

Those things aside, it looks nice :) If I ever need a library like that, I will download it.


To answer your first question, its a placeholder for future features.

Your second question: It's just to give illusion of 'using and forgetting'. I will implement your suggestion though. <edit>I guess I could implement IDisposable for that.</edit>

Thank you, I plan on adding more cool things in the future since I'm out for Winter break.

This post has been edited by Amrykid: 22 December 2011 - 11:49 AM

Was This Post Helpful? 0
  • +
  • -

#4 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2250
  • View blog
  • Posts: 9,432
  • Joined: 29-May 08

Re: Project Carbon

Posted 22 December 2011 - 12:31 PM

When would I use your solution, over say writing an enumerator or iterator.

Enumerator
Public Class Collatz
  Implements IEnumerator(of Long)
  Private _s,_n As Long
   Public Sub New(n As long)
    _s=n:  _n=n
  End Sub
  Public ReadOnly Property Current As Long Implements IEnumerator(Of Long).Current
    Get
      Return _n
    End Get
  End Property

  Public ReadOnly Property Current1 As Object Implements IEnumerator.Current
    Get
      Return Current 
    End Get
  End Property

  Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
    If _n = 1 then Return False
   Select Case (_n Mod 2)
    Case 0:   _n=_n\2
    Case 1: _n=(3*_n)+1 
   End Select
    Return True 
  End Function

  Public Sub Reset() Implements IEnumerator.Reset
    _n=_s
  End Sub

#Region "IDisposable Support"
  Private disposedValue As Boolean' To detect redundant calls

  ' IDisposable
  Protected   Overridable   Sub Dispose(disposing As Boolean)
    If Not Me.disposedValue Then
      If disposing Then
        ' TODO: dispose managed state (managed objects).
      End If

      ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
      ' TODO: set large fields to null.
    End If
    Me.disposedValue = True
  End Sub

  ' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
  'Protected Overrides Sub Finalize()
  '    ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
  '    Dispose(False)
  '    MyBase.Finalize()
  'End Sub

  ' This code added by Visual Basic to correctly implement the disposable pattern.
  Public Sub Dispose() Implements IDisposable.Dispose
    ' Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
    Dispose(True)
    GC.SuppressFinalize(Me)
  End Sub
#End Region

End Class



Iterator (VS11)
 Public Iterator Function Collatz_Conjecture( n As Long ) As IEnumerable(Of Long)
   Yield n
   Do 
    Select Case (n Mod 2)
     Case 0: n=n\2
     Case 1: n=(3*n)+1 
    End Select
   Yield n
  Loop Until n=1
 End Function 



Usage Example
Module Module1

  Sub Main()
    Dim x1=Collatz_Conjecture(25).ToList
    Dim x2=New Collatz(25)
    While x2.MoveNext 
      Console.WriteLine(x2.Current)
    End While
  End Sub
End Module



RX way
  Dim s=Reactive.Linq.Observable.Generate(Of Long,Long)(25,Function(n) n<>1,Function(n) If(n mod 2=0,n/2,(3*n)+1),Function(x) x)
    Dim su=s.Subscribe(onNext:= Sub(n) Console.WriteLine(n))


This post has been edited by AdamSpeight2008: 22 December 2011 - 12:52 PM

Was This Post Helpful? 1
  • +
  • -

#5 Amrykid  Icon User is offline

  • 4+1=Moo
  • member icon

Reputation: 148
  • View blog
  • Posts: 1,589
  • Joined: 16-December 08

Re: Project Carbon

Posted 22 December 2011 - 12:52 PM

View PostAdamSpeight2008, on 22 December 2011 - 02:31 PM, said:

When would I use your solution, over say writing an enumerator or iterator.

Enumerator
Public Class Collatz
  Implements IEnumerator(of Long)
  Private _s,_n As Long
   Public Sub New(n As long)
    _s=n:  _n=n
  End Sub
  Public ReadOnly Property Current As Long Implements IEnumerator(Of Long).Current
    Get
      Return _n
    End Get
  End Property

  Public ReadOnly Property Current1 As Object Implements IEnumerator.Current
    Get
      Return Current 
    End Get
  End Property

  Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
    If _n = 1 then Return False
   Select Case (_n Mod 2)
    Case 0:   _n=_n\2
    Case 1: _n=(3*_n)+1 
   End Select
    Return True 
  End Function

  Public Sub Reset() Implements IEnumerator.Reset
    _n=_s
  End Sub

#Region "IDisposable Support"
  Private disposedValue As Boolean' To detect redundant calls

  ' IDisposable
  Protected   Overridable   Sub Dispose(disposing As Boolean)
    If Not Me.disposedValue Then
      If disposing Then
        ' TODO: dispose managed state (managed objects).
      End If

      ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
      ' TODO: set large fields to null.
    End If
    Me.disposedValue = True
  End Sub

  ' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
  'Protected Overrides Sub Finalize()
  '    ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
  '    Dispose(False)
  '    MyBase.Finalize()
  'End Sub

  ' This code added by Visual Basic to correctly implement the disposable pattern.
  Public Sub Dispose() Implements IDisposable.Dispose
    ' Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
    Dispose(True)
    GC.SuppressFinalize(Me)
  End Sub
#End Region

End Class



Iterator (VS11)
 Public Iterator Function Collatz_Conjecture( n As Long ) As IEnumerable(Of Long)
   Yield n
   Do 
    Select Case (n Mod 2)
     Case 0: n=n\2
     Case 1: n=(3*n)+1 
    End Select
   Yield n
  Loop Until n=1
 End Function 



Usage Example
Module Module1

  Sub Main()
    Dim x1=Collatz_Conjecture(25).ToList
    Dim x2=New Collatz(25)
    While x2.MoveNext 
      Console.WriteLine(x2.Current)
    End While
  End Sub
End Module



When you put it that way, the only advantage I can see is that my code is asynchronous. So if an operation was performing long calculations or operations every cycle, it would not affect the application.

Of course, you could just use your code on a thread and achieve about the same effect. The point of mine is the handle the dirty work such as capturing exceptions and managing task at once.
Was This Post Helpful? 0
  • +
  • -

#6 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2250
  • View blog
  • Posts: 9,432
  • Joined: 29-May 08

Re: Project Carbon

Posted 22 December 2011 - 12:57 PM

I add a RX version to the post.
Was This Post Helpful? 0
  • +
  • -

#7 Amrykid  Icon User is offline

  • 4+1=Moo
  • member icon

Reputation: 148
  • View blog
  • Posts: 1,589
  • Joined: 16-December 08

Re: Project Carbon

Posted 22 December 2011 - 01:00 PM

Oh yeah, I noticed. In a way, my code is similar to RX, except mine is longer.

EDIT:
IIRC, Rx doesn't support Pause/Continue functionality. Carbon's RuntimeOperations does.

This post has been edited by Amrykid: 22 December 2011 - 01:15 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1