You're going to have trouble doing this 30 times per second for hours. Every compile will create a different in-memory assembly, and there's no way to unload a loaded assembly without tearing down the app domain. So your memory footprint will grow without bound.
If you want to prevent unbounded memory use, you have to compile and load the assembly in a separate app domain. You can then tear down that app domain to unload the loaded assembly.
But creating a new app domain, compiling an assembly, and tearing down an app domain 30 times per second? Possible, I suppose. Perhaps you could create an app domain and load assemblies into it for a minute, then tear down that app domain and create a new one. That would at least limit your memory usage somewhat, and also cut down on the processing. But I don't know what kind of footprint 1,800 loaded assemblies would have.
You definitely need to experiment with the System.CodeDom
namespace. I suspect, though, that you're asking a bit too much. The comment recommending an interpreted language might be the way to go. It's really hard to say without more information about your application.