I think what you are really asking is what is the difference between a function and an action (both are methods) in C#.
The difference has to do with how void is treated: this explains it pretty well https://softwareengineering.stackexchange.com/questions/131036/why-is-void-not-allowed-as-a-generic-type-in-c
I'll post Eric Lippert's answer in full to save a click:
The fundamental problem with "void" is that it does not mean the same thing as any other return type. "void" means "if this method
returns then it returns no value at all." Not null; null is a value.
It returns no value whatsoever.
This really messes up the type system. A type system is essentially a
system for making logical deductions about what operations are valid
on particular values; a void returning method doesn't return a value,
so the question "what operations are valid on this thing?" don't make
any sense at all. There's no "thing" for there to be an operation on,
valid or invalid.
Moreover, this messes up the runtime something fierce. The .NET
runtine is an implementation of the Virtual Execution System, which is
specified as a stack machine. That is, a virtual machine where the
operations are all characterized in terms of their effect on an
evaluation stack. (Of course in practice the machine will be
implemented on a machine with both stack and registers, but the
virtual execution system assumes just a stack.) The effect of a call
to a void method is fundamentally different than the effect of a call
to a non-void method; a non-void method always puts something on the
stack, which might need to be popped off. A void method never puts
something on the stack. And therefore the compiler cannot treat void
and non-void methods the same in the case where the method's returned
value is ignored; if the method is void then there is no return value
so there must be no pop.
For all these reasons, "void" is not a type that can be instantiated;
it has no values, that's its whole point. It's not convertible to
object, and a void returning method can never, ever be treated
polymorphically with a non-void-returning method because doing so
corrupts the stack!
Thus, void cannot be used as a type argument, which is a shame, as you
note. It would be very convenient.
With the benefit of hindsight, it would have been better for all
concerned if instead of nothing whatsoever, a void-returning method
automatically returned "Unit", a magical singleton reference type. You
would then know that every method call puts something on the stack,
you would know that every method call returns something that could be
assigned to a variable of object type, and of course Unit could be
used as a type argument, so there would be no need to have separate
Action and Func delegate types. Sadly, that's not the world we're in.
For some more thoughts in this vein see
http://blogs.msdn.com/b/ericlippert/archive/2009/06/29/the-void-is-invariant.aspx
and
http://blogs.msdn.com/b/ericlippert/archive/2011/02/21/never-say-never-part-one.aspx
and
http://blogs.msdn.com/b/ericlippert/archive/2011/11/28/why-have-a-stack.aspx