1 // 2 // Copyright (c) ZeroC, Inc. All rights reserved. 3 // 4 5 using System; 6 using System.Threading; 7 using System.Collections; 8 using System.Globalization; 9 10 namespace Ice 11 { 12 /// <summary> 13 /// Interface for thread notification hooks. Applications can derive 14 /// a class tat implements the start and stop 15 /// methods to intercept creation and destruction of threads created 16 /// by the Ice run time. 17 /// </summary> 18 public interface ThreadNotification 19 { 20 /// <summary> 21 /// The Ice run time calls start for each new 22 /// thread it creates. The call is made by the newly-started thread. 23 /// </summary> start()24 void start(); 25 26 /// <summary> 27 /// The Ice run time calls stop before it destroys 28 /// a thread. The call is made by thread that is about to be 29 /// destroyed. 30 /// </summary> stop()31 void stop(); 32 } 33 34 /// <summary> 35 /// A class that encpasulates data to initialize a communicator. 36 /// </summary> 37 public class InitializationData : ICloneable 38 { 39 /// <summary> 40 /// Creates and returns a copy of this object. 41 /// </summary> Clone()42 public object Clone() 43 { 44 // 45 // A member-wise copy is safe because the members are immutable. 46 // 47 return MemberwiseClone(); 48 } 49 50 /// <summary> 51 /// The properties for the communicator. 52 /// </summary> 53 public Properties properties; 54 55 /// <summary> 56 /// The logger for the communicator. 57 /// </summary> 58 public Logger logger; 59 60 /// <summary> 61 /// The communicator observer used by the Ice run-time. 62 /// </summary> 63 public Instrumentation.CommunicatorObserver observer; 64 65 /// <summary> 66 /// The thread hook for the communicator. 67 /// </summary> 68 [Obsolete("This data member is deprecated. Use threadStart or threadStop instead.")] 69 public ThreadNotification threadHook; 70 71 /// <summary> 72 /// The thread start hook for the communicator. The Ice run time 73 /// calls this hook for each new thread it creates. The call is 74 /// made by the newly-started thread. 75 /// </summary> 76 public System.Action threadStart; 77 78 /// <summary> 79 /// The thread stop hook for the communicator. The Ice run time 80 /// calls stop before it destroys a thread. The call is made by 81 /// thread that is about to be destroyed. 82 /// </summary> 83 public System.Action threadStop; 84 85 /// <summary> 86 /// The dispatcher for the communicator. 87 /// </summary> 88 public System.Action<System.Action, Connection> dispatcher; 89 90 /// <summary> 91 /// The compact type ID resolver. 92 /// </summary> 93 public System.Func<int, string> compactIdResolver; 94 95 /// <summary> 96 /// The batch request interceptor. 97 /// </summary> 98 public System.Action<BatchRequest, int, int> batchRequestInterceptor; 99 100 /// <summary> 101 /// The value factory manager. 102 /// </summary> 103 public ValueFactoryManager valueFactoryManager; 104 105 /// <summary> 106 /// The list of TypeId namespaces. Default is Ice.TypeId. 107 /// </summary> 108 public string[] typeIdNamespaces = { "Ice.TypeId" }; 109 } 110 111 /// <summary> 112 /// Utility methods for the Ice run time. 113 /// </summary> 114 public sealed class Util 115 { 116 /// <summary> 117 /// Creates a new empty property set. 118 /// </summary> 119 /// <returns>A new empty property set.</returns> createProperties()120 public static Properties createProperties() 121 { 122 return new PropertiesI(); 123 } 124 125 /// <summary> 126 /// Creates a property set initialized from an argument vector. 127 /// </summary> 128 /// <param name="args">A command-line argument vector, possibly containing 129 /// options to set properties. If the command-line options include 130 /// a --Ice.Config option, the corresponding configuration 131 /// files are parsed. If the same property is set in a configuration 132 /// file and in the argument vector, the argument vector takes precedence. 133 /// This method modifies the argument vector by removing any Ice-related options.</param> 134 /// <returns>A property set initialized with the property settings 135 /// that were removed from args.</returns> createProperties(ref string[] args)136 public static Properties createProperties(ref string[] args) 137 { 138 return new PropertiesI(ref args, null); 139 } 140 141 /// <summary> 142 /// Creates a property set initialized from an argument vector. 143 /// </summary> 144 /// <param name="args">A command-line argument vector, possibly containing 145 /// options to set properties. If the command-line options include 146 /// a --Ice.Config option, the corresponding configuration 147 /// files are parsed. If the same property is set in a configuration 148 /// file and in the argument vector, the argument vector takes precedence. 149 /// This method modifies the argument vector by removing any Ice-related options.</param> 150 /// <param name="defaults">Default values for the property set. Settings in configuration 151 /// files and args override these defaults.</param> 152 /// <returns>A property set initialized with the property settings 153 /// that were removed from args.</returns> createProperties(ref string[] args, Properties defaults)154 public static Properties createProperties(ref string[] args, Properties defaults) 155 { 156 return new PropertiesI(ref args, defaults); 157 } 158 159 /// <summary> 160 /// Creates a communicator. 161 /// </summary> 162 /// <param name="args">A command-line argument vector. Any Ice-related options 163 /// in this vector are used to intialize the communicator. 164 /// This method modifies the argument vector by removing any Ice-related options.</param> 165 /// <returns>The initialized communicator.</returns> initialize(ref string[] args)166 public static Communicator initialize(ref string[] args) 167 { 168 return initialize(ref args, (InitializationData)null); 169 } 170 171 /// <summary> 172 /// Creates a communicator. 173 /// </summary> 174 /// <param name="args">A command-line argument vector. Any Ice-related options 175 /// in this vector are used to initialize the communicator. 176 /// This method modifies the argument vector by removing any Ice-related options.</param> 177 /// <param name="initData">Additional intialization data. Property settings in args 178 /// override property settings in initData.</param> 179 /// <returns>The initialized communicator.</returns> initialize(ref string[] args, InitializationData initData)180 public static Communicator initialize(ref string[] args, InitializationData initData) 181 { 182 if(initData == null) 183 { 184 initData = new InitializationData(); 185 } 186 else 187 { 188 initData = (InitializationData)initData.Clone(); 189 } 190 191 initData.properties = createProperties(ref args, initData.properties); 192 193 CommunicatorI result = new CommunicatorI(initData); 194 result.finishSetup(ref args); 195 return result; 196 } 197 198 /// <summary> 199 /// Creates a communicator. 200 /// </summary> 201 /// <param name="args">A command-line argument vector. Any Ice-related options 202 /// in this vector are used to initialize the communicator. 203 /// This method modifies the argument vector by removing any Ice-related options.</param> 204 /// <param name="configFile">Path to a config file that sets the new communicator's default 205 /// properties.</param> 206 /// <returns>The initialized communicator.</returns> initialize(ref string[] args, string configFile)207 public static Communicator initialize(ref string[] args, string configFile) 208 { 209 InitializationData initData = null; 210 if(configFile != null) 211 { 212 initData = new InitializationData(); 213 initData.properties = Util.createProperties(); 214 initData.properties.load(configFile); 215 } 216 return initialize(ref args, initData); 217 } 218 219 /// <summary> 220 /// Creates a communicator. 221 /// </summary> 222 /// <param name="initData">Additional intialization data.</param> 223 /// <returns>The initialized communicator.</returns> initialize(InitializationData initData)224 public static Communicator initialize(InitializationData initData) 225 { 226 if(initData == null) 227 { 228 initData = new InitializationData(); 229 } 230 else 231 { 232 initData = (InitializationData)initData.Clone(); 233 } 234 235 CommunicatorI result = new CommunicatorI(initData); 236 string[] args = new string[0]; 237 result.finishSetup(ref args); 238 return result; 239 } 240 241 /// <summary> 242 /// Creates a communicator. 243 /// </summary> 244 /// <param name="configFile">Path to a config file that sets the new communicator's default 245 /// properties.</param> 246 /// <returns>The initialized communicator.</returns> initialize(string configFile)247 public static Communicator initialize(string configFile) 248 { 249 InitializationData initData = null; 250 if(configFile != null) 251 { 252 initData = new InitializationData(); 253 initData.properties = Util.createProperties(); 254 initData.properties.load(configFile); 255 } 256 return initialize(initData); 257 } 258 259 /// <summary> 260 /// Creates a communicator using a default configuration. 261 /// </summary> initialize()262 public static Communicator initialize() 263 { 264 return initialize((InitializationData)null); 265 } 266 267 /// <summary> 268 /// Converts a string to an object identity. 269 /// </summary> 270 /// <param name="s">The string to convert.</param> 271 /// <returns>The converted object identity.</returns> stringToIdentity(string s)272 public static Identity stringToIdentity(string s) 273 { 274 Identity ident = new Identity(); 275 276 // 277 // Find unescaped separator; note that the string may contain an escaped 278 // backslash before the separator. 279 // 280 int slash = -1, pos = 0; 281 while((pos = s.IndexOf((System.Char) '/', pos)) != -1) 282 { 283 int escapes = 0; 284 while(pos - escapes > 0 && s[pos - escapes - 1] == '\\') 285 { 286 escapes++; 287 } 288 289 // 290 // We ignore escaped escapes 291 // 292 if(escapes % 2 == 0) 293 { 294 if(slash == -1) 295 { 296 slash = pos; 297 } 298 else 299 { 300 // 301 // Extra unescaped slash found. 302 // 303 IdentityParseException ex = new IdentityParseException(); 304 ex.str = "unescaped backslash in identity `" + s + "'"; 305 throw ex; 306 } 307 } 308 pos++; 309 } 310 311 if(slash == -1) 312 { 313 ident.category = ""; 314 try 315 { 316 ident.name = IceUtilInternal.StringUtil.unescapeString(s, 0, s.Length, "/"); 317 } 318 catch(ArgumentException e) 319 { 320 IdentityParseException ex = new IdentityParseException(); 321 ex.str = "invalid identity name `" + s + "': " + e.Message; 322 throw ex; 323 } 324 } 325 else 326 { 327 try 328 { 329 ident.category = IceUtilInternal.StringUtil.unescapeString(s, 0, slash, "/"); 330 } 331 catch(ArgumentException e) 332 { 333 IdentityParseException ex = new IdentityParseException(); 334 ex.str = "invalid category in identity `" + s + "': " + e.Message; 335 throw ex; 336 } 337 if(slash + 1 < s.Length) 338 { 339 try 340 { 341 ident.name = IceUtilInternal.StringUtil.unescapeString(s, slash + 1, s.Length, "/"); 342 } 343 catch(ArgumentException e) 344 { 345 IdentityParseException ex = new IdentityParseException(); 346 ex.str = "invalid name in identity `" + s + "': " + e.Message; 347 throw ex; 348 } 349 } 350 else 351 { 352 ident.name = ""; 353 } 354 } 355 356 return ident; 357 } 358 359 /// <summary> 360 /// Converts an object identity to a string. 361 /// </summary> 362 /// <param name="ident">The object identity to convert.</param> 363 /// <param name="toStringMode">Specifies if and how non-printable ASCII characters are escaped in the result.</param> 364 /// <returns>The string representation of the object identity.</returns> identityToString(Identity ident, ToStringMode toStringMode = ToStringMode.Unicode)365 public static string identityToString(Identity ident, ToStringMode toStringMode = ToStringMode.Unicode) 366 { 367 if(ident.category == null || ident.category.Length == 0) 368 { 369 return IceUtilInternal.StringUtil.escapeString(ident.name, "/", toStringMode); 370 } 371 else 372 { 373 return IceUtilInternal.StringUtil.escapeString(ident.category, "/", toStringMode) + '/' + 374 IceUtilInternal.StringUtil.escapeString(ident.name, "/", toStringMode); 375 } 376 } 377 378 /// <summary> 379 /// This method is deprecated. Use System.Guid instead. 380 /// </summary> 381 [Obsolete("This method is deprecated. Use System.Guid instead.")] generateUUID()382 public static string generateUUID() 383 { 384 return Guid.NewGuid().ToString().ToUpper(System.Globalization.CultureInfo.InvariantCulture); 385 } 386 387 /// <summary> 388 /// Compares the object identities of two proxies. 389 /// </summary> 390 /// <param name="lhs">A proxy.</param> 391 /// <param name="rhs">A proxy.</param> 392 /// <returns>-1 if the identity in lhs compares 393 /// less than the identity in rhs; 0 if the identities 394 /// compare equal; 1, otherwise.</returns> proxyIdentityCompare(ObjectPrx lhs, ObjectPrx rhs)395 public static int proxyIdentityCompare(ObjectPrx lhs, ObjectPrx rhs) 396 { 397 if(lhs == null && rhs == null) 398 { 399 return 0; 400 } 401 else if(lhs == null && rhs != null) 402 { 403 return -1; 404 } 405 else if(lhs != null && rhs == null) 406 { 407 return 1; 408 } 409 else 410 { 411 Identity lhsIdentity = lhs.ice_getIdentity(); 412 Identity rhsIdentity = rhs.ice_getIdentity(); 413 int n; 414 n = string.CompareOrdinal(lhsIdentity.name, rhsIdentity.name); 415 if(n != 0) 416 { 417 return n; 418 } 419 return string.CompareOrdinal(lhsIdentity.category, rhsIdentity.category); 420 } 421 } 422 423 /// <summary> 424 /// Compares the object identities and facets of two proxies. 425 /// </summary> 426 /// <param name="lhs">A proxy.</param> 427 /// <param name="rhs">A proxy.</param> 428 /// <returns>-1 if the identity and facet in lhs compare 429 /// less than the identity and facet in rhs; 0 if the identities 430 /// and facets compare equal; 1, otherwise.</returns> proxyIdentityAndFacetCompare(ObjectPrx lhs, ObjectPrx rhs)431 public static int proxyIdentityAndFacetCompare(ObjectPrx lhs, ObjectPrx rhs) 432 { 433 if(lhs == null && rhs == null) 434 { 435 return 0; 436 } 437 else if(lhs == null && rhs != null) 438 { 439 return -1; 440 } 441 else if(lhs != null && rhs == null) 442 { 443 return 1; 444 } 445 else 446 { 447 Identity lhsIdentity = lhs.ice_getIdentity(); 448 Identity rhsIdentity = rhs.ice_getIdentity(); 449 int n; 450 n = string.CompareOrdinal(lhsIdentity.name, rhsIdentity.name); 451 if(n != 0) 452 { 453 return n; 454 } 455 n = string.CompareOrdinal(lhsIdentity.category, rhsIdentity.category); 456 if(n != 0) 457 { 458 return n; 459 } 460 461 string lhsFacet = lhs.ice_getFacet(); 462 string rhsFacet = rhs.ice_getFacet(); 463 if(lhsFacet == null && rhsFacet == null) 464 { 465 return 0; 466 } 467 else if(lhsFacet == null) 468 { 469 return -1; 470 } 471 else if(rhsFacet == null) 472 { 473 return 1; 474 } 475 else 476 { 477 return string.CompareOrdinal(lhsFacet, rhsFacet); 478 } 479 } 480 } 481 482 /// <summary> 483 /// Returns the process-wide logger. 484 /// </summary> 485 /// <returns>The process-wide logger.</returns> getProcessLogger()486 public static Logger getProcessLogger() 487 { 488 lock(_processLoggerMutex) 489 { 490 if(_processLogger == null) 491 { 492 _processLogger = new ConsoleLoggerI(AppDomain.CurrentDomain.FriendlyName); 493 } 494 return _processLogger; 495 } 496 } 497 498 /// <summary> 499 /// Changes the process-wide logger. 500 /// </summary> 501 /// <param name="logger">The new process-wide logger.</param> setProcessLogger(Logger logger)502 public static void setProcessLogger(Logger logger) 503 { 504 lock(_processLoggerMutex) 505 { 506 _processLogger = logger; 507 } 508 } 509 510 /// <summary> 511 /// Returns the Ice version in the form A.B.C, where A indicates the 512 /// major version, B indicates the minor version, and C indicates the 513 /// patch level. 514 /// </summary> 515 /// <returns>The Ice version.</returns> stringVersion()516 public static string stringVersion() 517 { 518 return "3.7.2"; // "A.B.C", with A=major, B=minor, C=patch 519 } 520 521 /// <summary> 522 /// Returns the Ice version as an integer in the form A.BB.CC, where A 523 /// indicates the major version, BB indicates the minor version, and CC 524 /// indicates the patch level. For example, for Ice 3.3.1, the returned value is 30301. 525 /// </summary> 526 /// <returns>The Ice version.</returns> intVersion()527 public static int intVersion() 528 { 529 return 30702; // AABBCC, with AA=major, BB=minor, CC=patch 530 } 531 532 /// <summary> 533 /// Converts a string to a protocol version. 534 /// </summary> 535 /// <param name="version">The string to convert.</param> 536 /// <returns>The converted protocol version.</returns> stringToProtocolVersion(string version)537 public static ProtocolVersion stringToProtocolVersion(string version) 538 { 539 byte major, minor; 540 stringToMajorMinor(version, out major, out minor); 541 return new ProtocolVersion(major, minor); 542 } 543 544 /// <summary> 545 /// Converts a string to an encoding version. 546 /// </summary> 547 /// <param name="version">The string to convert.</param> 548 /// <returns>The converted object identity.</returns> stringToEncodingVersion(string version)549 public static EncodingVersion stringToEncodingVersion(string version) 550 { 551 byte major, minor; 552 stringToMajorMinor(version, out major, out minor); 553 return new EncodingVersion(major, minor); 554 } 555 556 /// <summary> 557 /// Converts a protocol version to a string. 558 /// </summary> 559 /// <param name="v">The protocol version to convert.</param> 560 /// <returns>The converted string.</returns> protocolVersionToString(Ice.ProtocolVersion v)561 public static string protocolVersionToString(Ice.ProtocolVersion v) 562 { 563 return majorMinorToString(v.major, v.minor); 564 } 565 566 /// <summary> 567 /// Converts an encoding version to a string. 568 /// </summary> 569 /// <param name="v">The encoding version to convert.</param> 570 /// <returns>The converted string.</returns> encodingVersionToString(Ice.EncodingVersion v)571 public static string encodingVersionToString(Ice.EncodingVersion v) 572 { 573 return majorMinorToString(v.major, v.minor); 574 } 575 stringToMajorMinor(string str, out byte major, out byte minor)576 static private void stringToMajorMinor(string str, out byte major, out byte minor) 577 { 578 int pos = str.IndexOf('.'); 579 if(pos == -1) 580 { 581 throw new VersionParseException("malformed version value `" + str + "'"); 582 } 583 584 string majStr = str.Substring(0, (pos) - (0)); 585 string minStr = str.Substring(pos + 1, (str.Length) - (pos + 1)); 586 int majVersion; 587 int minVersion; 588 try 589 { 590 majVersion = int.Parse(majStr, CultureInfo.InvariantCulture); 591 minVersion = int.Parse(minStr, CultureInfo.InvariantCulture); 592 } 593 catch(FormatException) 594 { 595 throw new VersionParseException("invalid version value `" + str + "'"); 596 } 597 598 if(majVersion < 1 || majVersion > 255 || minVersion < 0 || minVersion > 255) 599 { 600 throw new VersionParseException("range error in version `" + str + "'"); 601 } 602 603 major = (byte)majVersion; 604 minor = (byte)minVersion; 605 } 606 majorMinorToString(byte major, byte minor)607 static private string majorMinorToString(byte major, byte minor) 608 { 609 return string.Format("{0}.{1}", major, minor); 610 } 611 registerPluginFactory(string name, PluginFactory factory, bool loadOnInit)612 public static void registerPluginFactory(string name, PluginFactory factory, bool loadOnInit) 613 { 614 PluginManagerI.registerPluginFactory(name, factory, loadOnInit); 615 } 616 617 public static readonly ProtocolVersion currentProtocol = 618 new ProtocolVersion(IceInternal.Protocol.protocolMajor, IceInternal.Protocol.protocolMinor); 619 620 public static readonly EncodingVersion currentProtocolEncoding = 621 new EncodingVersion(IceInternal.Protocol.protocolEncodingMajor, 622 IceInternal.Protocol.protocolEncodingMinor); 623 624 public static readonly EncodingVersion currentEncoding = 625 new EncodingVersion(IceInternal.Protocol.encodingMajor, IceInternal.Protocol.encodingMinor); 626 627 public static readonly ProtocolVersion Protocol_1_0 = new ProtocolVersion(1, 0); 628 629 public static readonly EncodingVersion Encoding_1_0 = new EncodingVersion(1, 0); 630 public static readonly EncodingVersion Encoding_1_1 = new EncodingVersion(1, 1); 631 632 public static readonly NoneType None = new NoneType(); 633 634 private static object _processLoggerMutex = new object(); 635 private static Logger _processLogger = null; 636 } 637 } 638 639 namespace IceInternal 640 { 641 public sealed class HashUtil 642 { hashAdd(ref int hashCode, bool value)643 public static void hashAdd(ref int hashCode, bool value) 644 { 645 hashCode = unchecked(((hashCode << 5) + hashCode) ^ value.GetHashCode()); 646 } 647 hashAdd(ref int hashCode, short value)648 public static void hashAdd(ref int hashCode, short value) 649 { 650 hashCode = unchecked(((hashCode << 5) + hashCode) ^ (int)(2654435761 * value)); 651 } 652 hashAdd(ref int hashCode, byte value)653 public static void hashAdd(ref int hashCode, byte value) 654 { 655 hashCode = unchecked(((hashCode << 5) + hashCode) ^ (int)(2654435761 * value)); 656 } 657 hashAdd(ref int hashCode, int value)658 public static void hashAdd(ref int hashCode, int value) 659 { 660 hashCode = unchecked(((hashCode << 5) + hashCode) ^ (int)(2654435761 * value)); 661 } 662 hashAdd(ref int hashCode, long value)663 public static void hashAdd(ref int hashCode, long value) 664 { 665 hashCode = unchecked(((hashCode << 5) + hashCode) ^ value.GetHashCode()); 666 } 667 hashAdd(ref int hashCode, float value)668 public static void hashAdd(ref int hashCode, float value) 669 { 670 hashCode = unchecked(((hashCode << 5) + hashCode) ^ value.GetHashCode()); 671 } 672 hashAdd(ref int hashCode, double value)673 public static void hashAdd(ref int hashCode, double value) 674 { 675 hashCode = unchecked(((hashCode << 5) + hashCode) ^ value.GetHashCode()); 676 } 677 hashAdd(ref int hashCode, object value)678 public static void hashAdd(ref int hashCode, object value) 679 { 680 if(value != null) 681 { 682 hashCode = unchecked(((hashCode << 5) + hashCode) ^ value.GetHashCode()); 683 } 684 } 685 hashAdd(ref int hashCode, object[] arr)686 public static void hashAdd(ref int hashCode, object[] arr) 687 { 688 if(arr != null) 689 { 690 hashCode = unchecked(((hashCode << 5) + hashCode) ^ IceUtilInternal.Arrays.GetHashCode(arr)); 691 } 692 } 693 hashAdd(ref int hashCode, Array arr)694 public static void hashAdd(ref int hashCode, Array arr) 695 { 696 if(arr != null) 697 { 698 hashCode = unchecked(((hashCode << 5) + hashCode) ^ IceUtilInternal.Arrays.GetHashCode(arr)); 699 } 700 } 701 hashAdd(ref int hashCode, IEnumerable s)702 public static void hashAdd(ref int hashCode, IEnumerable s) 703 { 704 if(s != null) 705 { 706 hashCode = unchecked(((hashCode << 5) + hashCode) ^ IceUtilInternal.Collections.SequenceGetHashCode(s)); 707 } 708 } 709 hashAdd(ref int hashCode, IDictionary d)710 public static void hashAdd(ref int hashCode, IDictionary d) 711 { 712 if(d != null) 713 { 714 hashCode = unchecked(((hashCode << 5) + hashCode) ^ IceUtilInternal.Collections.DictionaryGetHashCode(d)); 715 } 716 } 717 } 718 719 public sealed class Util 720 { getInstance(Ice.Communicator communicator)721 public static Instance getInstance(Ice.Communicator communicator) 722 { 723 Ice.CommunicatorI p = (Ice.CommunicatorI) communicator; 724 return p.getInstance(); 725 } 726 getProtocolPluginFacade(Ice.Communicator communicator)727 public static ProtocolPluginFacade getProtocolPluginFacade(Ice.Communicator communicator) 728 { 729 return new ProtocolPluginFacadeI(communicator); 730 } 731 stringToThreadPriority(string s)732 public static ThreadPriority stringToThreadPriority(string s) 733 { 734 if(string.IsNullOrEmpty(s)) 735 { 736 return ThreadPriority.Normal; 737 } 738 if(s.StartsWith("ThreadPriority.", StringComparison.Ordinal)) 739 { 740 s = s.Substring("ThreadPriority.".Length, s.Length); 741 } 742 if(s.Equals("Lowest")) 743 { 744 return ThreadPriority.Lowest; 745 } 746 else if(s.Equals("BelowNormal")) 747 { 748 return ThreadPriority.BelowNormal; 749 } 750 else if(s.Equals("Normal")) 751 { 752 return ThreadPriority.Normal; 753 } 754 else if(s.Equals("AboveNormal")) 755 { 756 return ThreadPriority.AboveNormal; 757 } 758 else if(s.Equals("Highest")) 759 { 760 return ThreadPriority.Highest; 761 } 762 return ThreadPriority.Normal; 763 } 764 } 765 } 766