put user defined userAgentString to the beginning of userAgentString
diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs
index ec60354..d8d43c7 100644
--- a/src/csharp/Grpc.Core/Channel.cs
+++ b/src/csharp/Grpc.Core/Channel.cs
@@ -32,8 +32,6 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
-using System.Runtime.InteropServices;
-using System.Threading;
 using System.Threading.Tasks;
 
 using Grpc.Core.Internal;
@@ -57,7 +55,7 @@
         readonly string target;
         readonly GrpcEnvironment environment;
         readonly ChannelSafeHandle handle;
-        readonly List<ChannelOption> options;
+        readonly Dictionary<string, ChannelOption> options;
 
         bool shutdownRequested;
 
@@ -71,12 +69,12 @@
         public Channel(string target, ChannelCredentials credentials, IEnumerable<ChannelOption> options = null)
         {
             this.target = Preconditions.CheckNotNull(target, "target");
-            this.environment = GrpcEnvironment.AddRef();
-            this.options = options != null ? new List<ChannelOption>(options) : new List<ChannelOption>();
-
+            this.options = CreateOptionsDictionary(options);
             EnsureUserAgentChannelOption(this.options);
+            this.environment = GrpcEnvironment.AddRef();
+
             using (var nativeCredentials = credentials.ToNativeCredentials())
-            using (var nativeChannelArgs = ChannelOptions.CreateChannelArgs(this.options))
+            using (var nativeChannelArgs = ChannelOptions.CreateChannelArgs(this.options.Values))
             {
                 if (nativeCredentials != null)
                 {
@@ -233,18 +231,36 @@
             activeCallCounter.Decrement();
         }
 
-        private static void EnsureUserAgentChannelOption(List<ChannelOption> options)
+        private static void EnsureUserAgentChannelOption(Dictionary<string, ChannelOption> options)
         {
-            if (!options.Any((option) => option.Name == ChannelOptions.PrimaryUserAgentString))
+            var key = ChannelOptions.PrimaryUserAgentString;
+            var userAgentString = "";
+
+            ChannelOption option;
+            if (options.TryGetValue(key, out option))
             {
-                options.Add(new ChannelOption(ChannelOptions.PrimaryUserAgentString, GetUserAgentString()));
-            }
+                // user-provided userAgentString needs to be at the beginning
+                userAgentString = option.StringValue + " ";
+            };
+
+            // TODO(jtattermusch): it would be useful to also provide .NET/mono version.
+            userAgentString += string.Format("grpc-csharp/{0}", VersionInfo.CurrentVersion);
+
+            options[ChannelOptions.PrimaryUserAgentString] = new ChannelOption(key, userAgentString);
         }
 
-        private static string GetUserAgentString()
+        private static Dictionary<string, ChannelOption> CreateOptionsDictionary(IEnumerable<ChannelOption> options)
         {
-            // TODO(jtattermusch): it would be useful to also provide .NET/mono version.
-            return string.Format("grpc-csharp/{0}", VersionInfo.CurrentVersion);
+            var dict = new Dictionary<string, ChannelOption>();
+            if (options == null)
+            {
+                return dict;
+            }
+            foreach (var option in options)
+            {
+                dict.Add(option.Name, option);
+            }
+            return dict;
         }
     }
 }