diff --git a/DiscordSharp.Commands/CommandStub.cs b/.NET core/DiscordSharp.Commands/CommandStub.cs similarity index 100% rename from DiscordSharp.Commands/CommandStub.cs rename to .NET core/DiscordSharp.Commands/CommandStub.cs diff --git a/DiscordSharp.Commands/CommandsManager.cs b/.NET core/DiscordSharp.Commands/CommandsManager.cs similarity index 100% rename from DiscordSharp.Commands/CommandsManager.cs rename to .NET core/DiscordSharp.Commands/CommandsManager.cs diff --git a/.NET core/DiscordSharp.Commands/DiscordSharp.Commands.csproj b/.NET core/DiscordSharp.Commands/DiscordSharp.Commands.csproj new file mode 100644 index 0000000..a138972 --- /dev/null +++ b/.NET core/DiscordSharp.Commands/DiscordSharp.Commands.csproj @@ -0,0 +1,11 @@ + + + + netcoreapp2.0 + + + + + + + diff --git a/DiscordSharp.Commands/ICommand.cs b/.NET core/DiscordSharp.Commands/ICommand.cs similarity index 100% rename from DiscordSharp.Commands/ICommand.cs rename to .NET core/DiscordSharp.Commands/ICommand.cs diff --git a/DiscordSharp.Commands/IDGenerator.cs b/.NET core/DiscordSharp.Commands/IDGenerator.cs similarity index 100% rename from DiscordSharp.Commands/IDGenerator.cs rename to .NET core/DiscordSharp.Commands/IDGenerator.cs diff --git a/DiscordSharp.Commands/IModule.cs b/.NET core/DiscordSharp.Commands/IModule.cs similarity index 100% rename from DiscordSharp.Commands/IModule.cs rename to .NET core/DiscordSharp.Commands/IModule.cs diff --git a/DiscordSharp.Commands/Permission.cs b/.NET core/DiscordSharp.Commands/Permission.cs similarity index 100% rename from DiscordSharp.Commands/Permission.cs rename to .NET core/DiscordSharp.Commands/Permission.cs diff --git a/.NET core/DiscordSharp.sln b/.NET core/DiscordSharp.sln new file mode 100644 index 0000000..7e4c30c --- /dev/null +++ b/.NET core/DiscordSharp.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2010 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordSharp", "DiscordSharp\DiscordSharp.csproj", "{83B812D1-C6A7-4378-825F-F7B21575ADDA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordSharp.Commands", "DiscordSharp.Commands\DiscordSharp.Commands.csproj", "{D0A7320C-33CA-455D-886B-86088C083903}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {83B812D1-C6A7-4378-825F-F7B21575ADDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {83B812D1-C6A7-4378-825F-F7B21575ADDA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {83B812D1-C6A7-4378-825F-F7B21575ADDA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {83B812D1-C6A7-4378-825F-F7B21575ADDA}.Release|Any CPU.Build.0 = Release|Any CPU + {D0A7320C-33CA-455D-886B-86088C083903}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D0A7320C-33CA-455D-886B-86088C083903}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D0A7320C-33CA-455D-886B-86088C083903}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D0A7320C-33CA-455D-886B-86088C083903}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4076345A-687A-4117-890D-F43D786881E1} + EndGlobalSection +EndGlobal diff --git a/DiscordSharp/Color.cs b/.NET core/DiscordSharp/Color.cs similarity index 100% rename from DiscordSharp/Color.cs rename to .NET core/DiscordSharp/Color.cs diff --git a/DiscordSharp/DiscordClient.cs b/.NET core/DiscordSharp/DiscordClient.cs similarity index 87% rename from DiscordSharp/DiscordClient.cs rename to .NET core/DiscordSharp/DiscordClient.cs index a9d8c14..9f44d4c 100644 --- a/DiscordSharp/DiscordClient.cs +++ b/.NET core/DiscordSharp/DiscordClient.cs @@ -3,17 +3,17 @@ using Newtonsoft.Json; using System.Net; using System.IO; -using WebSocketSharp; using System.Threading; using System.Collections.Generic; using Newtonsoft.Json.Linq; using DiscordSharp.Events; -using System.Text.RegularExpressions; using System.Drawing; +using System.Linq; using DiscordSharp.Objects; - -using ID = System.String; using DiscordSharp.Sockets; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using DiscordSharp.Sockets.BuiltIn; namespace DiscordSharp { @@ -118,6 +118,12 @@ public class DiscordClient /// public DiscordProperties DiscordProperties { get; set; } = new DiscordProperties(); + /// + /// Custom properties for the default discord channel to listen to + /// This updates with various events such as offline/online status + /// + public string[] DiscordSyncedGuilds { get; set; } = new string[] { }; + /// /// The current DiscordMember object assosciated with the account you're connected to. /// @@ -163,11 +169,10 @@ public class DiscordClient public bool Autoconnect { get; set; } = true; - private IDiscordWebSocket ws; + private NetWebSocketWrapper ws; private List ServersList { get; set; } private string CurrentGameName = ""; private int? IdleSinceUnixTime = null; - static string UserAgentString = $" (http://github.com/Luigifan/DiscordSharp, {typeof(DiscordClient).Assembly.GetName().Version.ToString()})"; private DiscordVoiceClient VoiceClient; private Logger DebugLogger = new Logger(); private CancellationTokenSource KeepAliveTaskTokenSource = new CancellationTokenSource(); @@ -197,7 +202,7 @@ public class DiscordClient /// A log of messages kept in a KeyValuePair. /// The key is the id of the message, and the value is a DiscordMessage object. If you need raw json, this is contained inside of the DiscordMessage object now. /// - private Dictionary MessageLog = new Dictionary(); + private Dictionary MessageLog = new Dictionary(); //private List> MessageLog = new List>(); private List PrivateChannels = new List(); @@ -236,6 +241,7 @@ public class DiscordClient public event EventHandler RoleUpdated; public event EventHandler GuildMemberUpdated; public event EventHandler GuildMemberBanned; + public event EventHandler GuildMembersLoadedEventArgs; public event EventHandler PrivateChannelDeleted; public event EventHandler BanRemoved; public event EventHandler PrivateMessageDeleted; @@ -278,11 +284,6 @@ public DiscordClient(string tokenOverride = null, bool isBotAccount = false, boo token = tokenOverride; IsBotAccount = isBotAccount; - if (IsBotAccount) - UserAgentString = "DiscordBot " + UserAgentString; - else - UserAgentString = "Custom Discord Client " + UserAgentString; - if (ClientPrivateInformation == null) ClientPrivateInformation = new DiscordUserInformation(); @@ -290,8 +291,7 @@ public DiscordClient(string tokenOverride = null, bool isBotAccount = false, boo { if (e.message.Level == MessageLevel.Error) DisconnectFromVoice(); - if (TextClientDebugMessageReceived != null) - TextClientDebugMessageReceived(this, e); + TextClientDebugMessageReceived?.Invoke(this, e); }; } @@ -305,7 +305,7 @@ public DiscordClient(string tokenOverride = null, bool isBotAccount = false, boo /// Any messages logged since connection to the websocket. /// /// A KeyValuePair list of string-DiscordMessage. Where string is the message's ID - public Dictionary GetMessageLog() => MessageLog; + public Dictionary GetMessageLog() => MessageLog; /// /// Private channels assosciated with the account. @@ -417,11 +417,11 @@ private void GetChannelsList(JObject m) if (!presence["game"].IsNullOrEmpty()) { member.CurrentGame = presence["game"]["name"].ToString(); - if (presence["d"]["game"]["type"].ToObject() == 1) + if (presence["game"]["type"].ToObject() == 1) { member.Streaming = true; - if (presence["d"]["game"]["url"].ToString() != null) - member.StreamURL = presence["d"]["game"]["url"].ToString(); + if (presence["game"]["url"].ToString() != null) + member.StreamURL = presence["game"]["url"].ToString(); } } } @@ -433,36 +433,40 @@ private void GetChannelsList(JObject m) } if (PrivateChannels == null) PrivateChannels = new List(); - foreach (var privateChannel in m["d"]["private_channels"]) + foreach (JObject privateChannel in m["d"]["private_channels"]) { - DiscordPrivateChannel tempPrivate = JsonConvert.DeserializeObject(privateChannel.ToString()); - tempPrivate.Client = this; - tempPrivate.user_id = privateChannel["recipient"]["id"].ToString(); - DiscordServer potentialServer = new DiscordServer(); - ServersList.ForEach(x => + foreach (JObject recepient in privateChannel["recipients"]) { - if (x.GetMemberByKey(privateChannel["recipient"]["id"].ToString()) != null) + DiscordPrivateChannel tempPrivate = JsonConvert.DeserializeObject(privateChannel.ToString()); + tempPrivate.Client = this; + tempPrivate.user_id = recepient["id"].ToString(); + DiscordServer potentialServer = new DiscordServer(); + ServersList.ForEach(x => { - potentialServer = x; - } - }); - if (potentialServer.Owner != null) //should be a safe test..i hope - { - DiscordMember recipient = potentialServer.GetMemberByKey(privateChannel["recipient"]["id"].ToString()); - if (recipient != null) + if (x.GetMemberByKey(recepient["id"].ToString()) != null) + { + potentialServer = x; + } + }); + if (potentialServer.Owner != null) //should be a safe test..i hope { - tempPrivate.Recipient = recipient; + DiscordMember recipient = potentialServer.GetMemberByKey(recepient["id"].ToString()); + if (recipient != null) + { + tempPrivate.Recipient = recipient; + } + else + { + DebugLogger.Log("Recipient was null!!!!", MessageLevel.Critical); + } } else { - DebugLogger.Log("Recipient was null!!!!", MessageLevel.Critical); + DebugLogger.Log("No potential server found for user's private channel null! This will probably fix itself.", MessageLevel.Debug); } + PrivateChannels.Add(tempPrivate); } - else - { - DebugLogger.Log("No potential server found for user's private channel null! This will probably fix itself.", MessageLevel.Debug); - } - PrivateChannels.Add(tempPrivate); + } } @@ -891,7 +895,7 @@ private DiscordMessage SendActualMessage(string id, string message, DiscordMembe /// The game's name. Old gameid lookup can be seen at: http://hastebin.com/azijiyaboc.json/ /// Whether or not you want your bot to appear as if it is streaming. True means it will show it's streaming. /// The 'url' for the stream, if your bot is streaming. - public void UpdateCurrentGame(string gameName, bool streaming, string url = null) + public async void UpdateCurrentGame(string gameName, bool streaming, string url = null) { string msg; if (gameName.ToLower().Trim() != "") @@ -928,14 +932,14 @@ public void UpdateCurrentGame(string gameName, bool streaming, string url = null }); DebugLogger.Log("Setting current game to null."); } - ws.Send(msg.ToString()); + await ws.SendMessage(msg.ToString()); } /// /// Updates the bot's status. /// /// True if you want the bot to report as idle. - public void UpdateBotStatus(bool idle) + public async void UpdateBotStatus(bool idle) { string msg; msg = JsonConvert.SerializeObject( @@ -948,7 +952,7 @@ public void UpdateBotStatus(bool idle) game = CurrentGameName.ToLower().Trim() == "" ? (object)null : new { name = CurrentGameName } } }); - ws.Send(msg.ToString()); //let's try it! + await ws.SendMessage(msg.ToString()); //let's try it! } private void PresenceUpdateEvents(JObject message) @@ -1159,7 +1163,7 @@ public DiscordMember GetMemberFromChannel(DiscordChannelBase channel, string use DebugLogger.Log("Error in GetMemberFromChannel: foundMember was null!", MessageLevel.Error); } } - else if(channel.GetType() == typeof(DiscordPrivateChannel)) + else if (channel.GetType() == typeof(DiscordPrivateChannel)) { return ((DiscordPrivateChannel)channel).Recipient; } @@ -1192,7 +1196,7 @@ public DiscordMember GetMemberFromChannel(DiscordChannelBase channel, string id) DebugLogger.Log($"Error in GetMemberFromChannel: foundMember was null! ID: {id}", MessageLevel.Error); } } - else if(channel.GetType() == typeof(DiscordPrivateChannel)) + else if (channel.GetType() == typeof(DiscordPrivateChannel)) { return ((DiscordPrivateChannel)channel).Recipient; } @@ -1211,14 +1215,12 @@ public DiscordMember GetMemberFromChannel(DiscordChannelBase channel, string id) /// public DiscordChannel GetChannelByName(string channelName) { - try + DiscordServer findServer = ServersList.Where(x => x.Channels.Find(y => y.Name.ToLower() == channelName.ToLower()) != null).FirstOrDefault(); + if (findServer != null) { - return ServersList.Find(x => x.Channels.Find(y => y.Name.ToLower() == channelName.ToLower()) != null).Channels.Find(x => x.Name.ToLower() == channelName.ToLower()); - } - catch - { - return null; + return findServer.Channels.Where(x => x.Name.ToLower() == channelName.ToLower()).FirstOrDefault(); } + return null; } /// @@ -1228,7 +1230,32 @@ public DiscordChannel GetChannelByName(string channelName) /// public DiscordChannel GetChannelByID(long id) { - return ServersList.Find(x => x.Channels.Find(y => y.ID == id.ToString()) != null).Channels.Find(z => z.ID == id.ToString()); + foreach (DiscordServer server in ServersList) + { + foreach (DiscordChannel channel in server.Channels) + { + if (channel.ID != null && channel.ID == id.ToString()) + { + return channel; + } + } + } + return null; + } + + public DiscordServer GetServerByChannelID(long id) + { + foreach (DiscordServer server in ServersList) + { + foreach (DiscordChannel channel in server.Channels) + { + if (channel.ID != null && channel.ID == id.ToString()) + { + return server; + } + } + } + return null; } /// @@ -1335,10 +1362,7 @@ public DiscordMessage EditMessage(string MessageID, string replacementMessage, D private void SendDeleteRequest(DiscordMessage message) { string url; - //if(!user) url = Endpoints.BaseAPI + Endpoints.Channels + $"/{message.channel.ID}" + Endpoints.Messages + $"/{message.ID}"; - //else - //url = Endpoints.BaseAPI + Endpoints.Channels + $"/{message.channel.id}" + Endpoints.Messages + $"/{message.id}"; try { var result = WebWrapper.Delete(url, token); @@ -1349,7 +1373,7 @@ private void SendDeleteRequest(DiscordMessage message) } } - private DiscordMessage FindInMessageLog(ID id) + private DiscordMessage FindInMessageLog(String id) { foreach (var message in MessageLog) if (message.Key == id) @@ -1455,105 +1479,124 @@ private DiscordChannel GetDiscordChannelByID(string id) private void MessageCreateEvents(JObject message) { - //try - //{ - string tempChannelID = message["d"]["channel_id"].ToString(); - - //DiscordServer foundServerChannel = ServersList.Find(x => x.channels.Find(y => y.id == tempChannelID) != null); - DiscordChannel potentialChannel = GetDiscordChannelByID(message["d"]["channel_id"].ToString()); - if (potentialChannel == null) //private message create + try { - if (message["d"]["author"]["id"].ToString() != Me.ID) - { - var foundPM = PrivateChannels.Find(x => x.ID == message["d"]["channel_id"].ToString()); - DiscordPrivateMessageEventArgs dpmea = new DiscordPrivateMessageEventArgs(); - dpmea.Channel = foundPM; - dpmea.Message = message["d"]["content"].ToString(); - DiscordMember tempMember = new DiscordMember(this); - tempMember.Username = message["d"]["author"]["username"].ToString(); - tempMember.ID = message["d"]["author"]["id"].ToString(); - dpmea.Author = tempMember; - tempMember.parentclient = this; - dpmea.RawJson = message; + string tempChannelID = message["d"]["channel_id"].ToString(); - if (PrivateMessageReceived != null) - PrivateMessageReceived(this, dpmea); + //DiscordServer foundServerChannel = ServersList.Find(x => x.channels.Find(y => y.id == tempChannelID) != null); + DiscordChannel potentialChannel = GetDiscordChannelByID(message["d"]["channel_id"].ToString()); + if (potentialChannel == null) //private message create + { + if (message["d"]["author"]["id"].ToString() != Me.ID) + { + var foundPM = PrivateChannels.Find(x => x.ID == message["d"]["channel_id"].ToString()); + DiscordPrivateMessageEventArgs dpmea = new DiscordPrivateMessageEventArgs(); + dpmea.Channel = foundPM; + dpmea.Message = message["d"]["content"].ToString(); + DiscordMember tempMember = new DiscordMember(this); + tempMember.Username = message["d"]["author"]["username"].ToString(); + tempMember.ID = message["d"]["author"]["id"].ToString(); + dpmea.Author = tempMember; + tempMember.parentclient = this; + dpmea.RawJson = message; + + PrivateMessageReceived?.Invoke(this, dpmea); + } + else + { + //if (DebugMessageReceived != null) + // DebugMessageReceived(this, new DiscordDebugMessagesEventArgs { message = "Ignoring MESSAGE_CREATE for private channel for message sent from this client." }); + } } else { - //if (DebugMessageReceived != null) - // DebugMessageReceived(this, new DiscordDebugMessagesEventArgs { message = "Ignoring MESSAGE_CREATE for private channel for message sent from this client." }); - } - } - else - { - DiscordMessageEventArgs dmea = new DiscordMessageEventArgs(); - dmea.RawJson = message; - dmea.Channel = potentialChannel; + DiscordMessageEventArgs dmea = new DiscordMessageEventArgs(); + dmea.RawJson = message; + dmea.Channel = potentialChannel; - dmea.MessageText = message["d"]["content"].ToString(); + dmea.MessageText = message["d"]["content"].ToString(); - DiscordMember tempMember = null; - tempMember = potentialChannel.Parent.GetMemberByKey(message["d"]["author"]["id"].ToString()); - if (tempMember == null) - { - tempMember = JsonConvert.DeserializeObject(message["author"].ToString()); - tempMember.parentclient = this; - tempMember.Parent = potentialChannel.Parent; - - potentialChannel.Parent.AddMember(tempMember); - } + DiscordMember tempMember = null; + if (potentialChannel.Parent != null) // Server not sync-ed yet. We need to re-request data + { + tempMember = potentialChannel.Parent.GetMemberByKey(message["d"]["author"]["id"].ToString()); + if (tempMember == null) + { + tempMember = JsonConvert.DeserializeObject(message["author"].ToString()); + tempMember.parentclient = this; + tempMember.Parent = potentialChannel.Parent; - dmea.Author = tempMember; + potentialChannel.Parent.AddMember(tempMember); + } - DiscordMessage m = new DiscordMessage(); - m.Author = dmea.Author; - m.channel = dmea.Channel; - m.TypeOfChannelObject = dmea.Channel.GetType(); - m.Content = dmea.MessageText; - m.ID = message["d"]["id"].ToString(); - m.RawJson = message; - m.timestamp = DateTime.Now; - dmea.Message = m; - if (!message["d"]["attachments"].IsNullOrEmpty()) - { - List tempList = new List(); - foreach (var attachment in message["d"]["attachments"]) - { - tempList.Add(JsonConvert.DeserializeObject(attachment.ToString())); - } - m.Attachments = tempList.ToArray(); - } + dmea.Author = tempMember; + + DiscordMessage m = new DiscordMessage(); + m.Author = dmea.Author; + m.channel = dmea.Channel; + m.TypeOfChannelObject = dmea.Channel.GetType(); + m.Content = dmea.MessageText; + m.ID = message["d"]["id"].ToString(); + m.RawJson = message; + m.timestamp = DateTime.Now; + dmea.Message = m; + if (!message["d"]["attachments"].IsNullOrEmpty()) + { + List tempList = new List(); + foreach (var attachment in message["d"]["attachments"]) + { + tempList.Add(JsonConvert.DeserializeObject(attachment.ToString())); + } + m.Attachments = tempList.ToArray(); + } - if (!message["d"]["mentions"].IsNullOrEmpty()) - { - JArray mentionsAsArray = JArray.Parse(message["d"]["mentions"].ToString()); - foreach (var mention in mentionsAsArray) - { - string id = mention["id"].ToString(); - if (id.Equals(Me.ID)) + if (!message["d"]["mentions"].IsNullOrEmpty()) { - if (MentionReceived != null) - MentionReceived(this, dmea); + JArray mentionsAsArray = JArray.Parse(message["d"]["mentions"].ToString()); + foreach (var mention in mentionsAsArray) + { + string id = mention["id"].ToString(); + if (id.Equals(Me.ID)) + { + if (MentionReceived != null) + MentionReceived(this, dmea); + } + } } - } - } - KeyValuePair toAdd = new KeyValuePair(message["d"]["id"].ToString(), m); - MessageLog.Add(message["d"]["id"].ToString(), m); + KeyValuePair toAdd = new KeyValuePair(message["d"]["id"].ToString(), m); + MessageLog.Add(message["d"]["id"].ToString(), m); - if (MessageReceived != null) - MessageReceived(this, dmea); + MessageReceived?.Invoke(this, dmea); + } + } + } + catch (Exception ex) + { + DebugLogger.Log(string.Format("Error ocurred during MessageCreateEvents: {0}\r\n{1}", ex.Message, message.ToString()), MessageLevel.Error); } - //} - //catch (Exception ex) - //{ - // DebugLogger.Log("Error ocurred during MessageCreateEvents: " + ex.Message, MessageLevel.Error); - //} } private void ChannelCreateEvents(JObject message) { + /*{{ + "t": "CHANNEL_CREATE", + "s": 97, + "op": 0, + "d": { + "type": 1, + "recipients": [ + { + "username": "", + "id": "", + "discriminator": "8031", + "avatar": "" + } + ], + "last_message_id": null, + "id": "496435723788877835" + } +}}*/ if (message["d"]["is_private"].ToString().ToLower() == "false") { var foundServer = ServersList.Find(x => x.ID == message["d"]["guild_id"].ToString()); @@ -1569,11 +1612,12 @@ private void ChannelCreateEvents(JObject message) tempChannel.ID = message["d"]["id"].ToString(); tempChannel.Parent = foundServer; foundServer.Channels.Add(tempChannel); + DiscordChannelCreateEventArgs fae = new DiscordChannelCreateEventArgs(); fae.ChannelCreated = tempChannel; fae.ChannelType = DiscordChannelCreateType.CHANNEL; - if (ChannelCreated != null) - ChannelCreated(this, fae); + + ChannelCreated?.Invoke(this, fae); } } else @@ -1584,9 +1628,14 @@ private void ChannelCreateEvents(JObject message) DiscordMember recipient = ServersList.Find(x => x.GetMemberByKey(message["d"]["recipient"]["id"].ToString()) != null).GetMemberByKey(message["d"]["recipient"]["id"].ToString()); tempPrivate.Recipient = recipient; PrivateChannels.Add(tempPrivate); - DiscordPrivateChannelEventArgs fak = new DiscordPrivateChannelEventArgs { ChannelType = DiscordChannelCreateType.PRIVATE, ChannelCreated = tempPrivate }; - if (PrivateChannelCreated != null) - PrivateChannelCreated(this, fak); + + DiscordPrivateChannelEventArgs fak = new DiscordPrivateChannelEventArgs + { + ChannelType = DiscordChannelCreateType.PRIVATE, + ChannelCreated = tempPrivate + }; + + PrivateChannelCreated?.Invoke(this, fak); } } #endregion @@ -1863,7 +1912,7 @@ public void DeleteInvite(string id) /// /// If true, DiscordSharp will connect using the .Net Framework's built-in WebSocketClasses. /// Please do not use this on Mono or versions of Windows below 8/8.1 - public void Connect(bool useDotNetWebsocket = false) + public void Connect() { CurrentGatewayURL = GetGatewayUrl(); if (string.IsNullOrEmpty(CurrentGatewayURL)) @@ -1873,41 +1922,31 @@ public void Connect(bool useDotNetWebsocket = false) } DebugLogger.Log("Gateway retrieved: " + CurrentGatewayURL); - if (useDotNetWebsocket) - { - ws = new NetWebSocket(CurrentGatewayURL); - DebugLogger.Log("Using the built-in .Net websocket.."); - } - else - { - ws = new WebSocketSharpSocket(CurrentGatewayURL); - DebugLogger.Log("Using WebSocketSharp websocket.."); - } + ws = new NetWebSocketWrapper(CurrentGatewayURL); ws.MessageReceived += (sender, e) => { - var message = new JObject(); try { - message = JObject.Parse(e.Message); + var message = JObject.Parse(e.Message); + + if (EnableVerboseLogging) + if (message["t"].ToString() != "READY") + DebugLogger.Log(message.ToString(), MessageLevel.Unecessary); + + if (!message["t"].IsNullOrEmpty()) //contains a t parameter used for client events. + ClientPacketReceived(message); + else + MiscellaneousOpcodes(message); + + if (!message["s"].IsNullOrEmpty()) + Sequence = message["s"].ToObject(); } - catch(Exception ex) + catch (Exception ex) { DebugLogger.Log($"MessageReceived Error: {ex.Message}\n\n```{e.Message}\n```\n", MessageLevel.Error); + return; } - - if (EnableVerboseLogging) - if (message["t"].ToString() != "READY") - DebugLogger.Log(message.ToString(), MessageLevel.Unecessary); - - if (!message["t"].IsNullOrEmpty()) //contains a t parameter used for client events. - ClientPacketReceived(message); - else - MiscellaneousOpcodes(message); - - if (!message["s"].IsNullOrEmpty()) - Sequence = message["s"].ToObject(); - }; ws.SocketOpened += (sender, e) => { @@ -1931,9 +1970,10 @@ public void Connect(bool useDotNetWebsocket = false) DebugLogger.Log("Connecting.."); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private void MiscellaneousOpcodes(JObject message) { - switch (message["d"].ToObject()) + switch (message["op"].ToObject()) { case Opcodes.INVALIDATE_SESSION: // TODO: the session was invalidated and a full reconnection must be performed. @@ -1956,137 +1996,152 @@ private void PerformReconnection() }); } - private void ClientPacketReceived(JObject message) - { - switch (message["t"].ToString()) - { - case ("READY"): - Sequence = message["s"].ToObject(); - DiscordGatewayVersion = message["d"]["v"].ToObject(); - HeartbeatInterval = message["d"]["heartbeat_interval"].ToObject(); - BeginHeartbeatTask(); - if (WriteLatestReady) - using (var sw = new StreamWriter("READY_LATEST.txt")) - sw.Write(message); - Me = JsonConvert.DeserializeObject(message["d"]["user"].ToString()); - Me.parentclient = this; - IsBotAccount = message["d"]["user"]["bot"].IsNullOrEmpty() ? false : message["d"]["user"]["bot"].ToObject(); - ClientPrivateInformation.Avatar = Me.Avatar; - ClientPrivateInformation.Username = Me.Username; - GetChannelsList(message); - SessionID = message["d"]["session_id"].ToString(); - - //TESTING - string[] guildID = new string[ServersList.Count]; - for (int i = 0; i < guildID.Length; i++) - guildID[i] = ServersList[i].ID; - - if (RequestAllUsersOnStartup) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private async void ClientPacketReceived(JObject message) + { + string header = message["t"].ToString(); + + Debug.WriteLine(string.Format("[DiscordClient] Received {0} HEADER.", header)); + + switch (header) + { + case "READY": { - string wsChunkTest = JsonConvert.SerializeObject(new + Sequence = message["s"].ToObject(); + DiscordGatewayVersion = message["d"]["v"].ToObject(); + if (message["d"]?["heartbeat_interval"] != null) + HeartbeatInterval = message["d"]["heartbeat_interval"].ToObject(); + BeginHeartbeatTask(); + + if (WriteLatestReady) { - op = 8, - d = new + using (var sw = new StreamWriter("READY_LATEST.txt")) { - guild_id = guildID, - query = "", - limit = 0 + sw.Write(message); } - }); - ws.Send(wsChunkTest); - } + } - ReadyComplete = true; + Me = JsonConvert.DeserializeObject(message["d"]["user"].ToString()); + Me.parentclient = this; + IsBotAccount = message["d"]["user"]["bot"].IsNullOrEmpty() ? false : message["d"]["user"]["bot"].ToObject(); + ClientPrivateInformation.Avatar = Me.Avatar; + ClientPrivateInformation.Username = Me.Username; + GetChannelsList(message); + SessionID = message["d"]["session_id"].ToString(); - Task.Run(() => - { - Task.Delay(3000); - Connected?.Invoke(this, new DiscordConnectEventArgs { User = Me }); - }); //fire and forget waiting of up to 3 seconds for guilds to become available. - break; - case ("GUILD_MEMBERS_CHUNK"): + //TESTING + string[] guildID = new string[ServersList.Count]; + for (int i = 0; i < guildID.Length; i++) + guildID[i] = ServersList[i].ID; + + if (RequestAllUsersOnStartup) + { + string wsChunkTest = JsonConvert.SerializeObject(new + { + op = 8, + d = new + { + guild_id = guildID, + query = "", + limit = 0 + } + }); + await ws.SendMessage(wsChunkTest); + + //ws.Send(@"{""op"":4,""d"":{ ""guild_id"":null,""channel_id"":null,""self_mute"":true,""self_deaf"":false,""self_video"":false}}"); + } + + ReadyComplete = true; + + await Task.Run(() => + { + Task.Delay(3000); + Connected?.Invoke(this, new DiscordConnectEventArgs { User = Me }); + }); //fire and forget waiting of up to 3 seconds for guilds to become available. + break; + } + case "GUILD_MEMBERS_CHUNK": GuildMemberChunkEvents(message); break; - case ("GUILD_MEMBER_REMOVE"): + case "GUILD_MEMBER_REMOVE": GuildMemberRemoveEvents(message); break; - case ("GUILD_MEMBER_ADD"): + case "GUILD_MEMBER_ADD": GuildMemberAddEvents(message); break; - case ("GUILD_DELETE"): + case "GUILD_DELETE": GuildDeleteEvents(message); break; - case ("GUILD_CREATE"): + case "GUILD_CREATE": GuildCreateEvents(message); break; - case ("GUILD_MEMBER_UPDATE"): + case "GUILD_MEMBER_UPDATE": GuildMemberUpdateEvents(message); break; - case ("GUILD_UPDATE"): + case "GUILD_UPDATE": GuildUpdateEvents(message); break; - case ("GUILD_ROLE_DELETE"): + case "GUILD_ROLE_DELETE": GuildRoleDeleteEvents(message); break; - case ("GUILD_ROLE_UPDATE"): + case "GUILD_ROLE_UPDATE": GuildRoleUpdateEvents(message); break; - case ("PRESENCE_UPDATE"): + case "PRESENCE_UPDATE": PresenceUpdateEvents(message); break; - case ("MESSAGE_UPDATE"): + case "MESSAGE_UPDATE": MessageUpdateEvents(message); break; - case ("TYPING_START"): + case "TYPING_START": DiscordServer server = ServersList.Find(x => x.Channels.Find(y => y.ID == message["d"]["channel_id"].ToString()) != null); if (server != null) { DiscordChannel channel = server.Channels.Find(x => x.ID == message["d"]["channel_id"].ToString()); DiscordMember uuser = server.GetMemberByKey(message["d"]["user_id"].ToString()); - if (UserTypingStart != null) - UserTypingStart(this, new DiscordTypingStartEventArgs { user = uuser, Channel = channel, Timestamp = int.Parse(message["d"]["timestamp"].ToString()) }); + UserTypingStart?.Invoke(this, new DiscordTypingStartEventArgs { user = uuser, Channel = channel, Timestamp = int.Parse(message["d"]["timestamp"].ToString()) }); } break; - case ("MESSAGE_CREATE"): + case "MESSAGE_CREATE": MessageCreateEvents(message); break; - case ("CHANNEL_CREATE"): + case "CHANNEL_CREATE": ChannelCreateEvents(message); break; - case ("VOICE_STATE_UPDATE"): + case "VOICE_STATE_UPDATE": VoiceStateUpdateEvents(message); break; - case ("VOICE_SERVER_UPDATE"): + case "VOICE_SERVER_UPDATE": VoiceServerUpdateEvents(message); break; - case ("MESSAGE_DELETE"): + case "MESSAGE_DELETE": MessageDeletedEvents(message); break; - case ("USER_UPDATE"): + case "USER_UPDATE": UserUpdateEvents(message); break; - case ("CHANNEL_UPDATE"): + case "CHANNEL_UPDATE": ChannelUpdateEvents(message); break; - case ("CHANNEL_DELETE"): + case "CHANNEL_DELETE": ChannelDeleteEvents(message); break; - case ("GUILD_BAN_ADD"): + case "GUILD_BAN_ADD": GuildMemberBannedEvents(message); break; - case ("GUILD_BAN_REMOVE"): + case "GUILD_BAN_REMOVE": GuildMemberBanRemovedEvents(message); break; - case ("MESSAGE_ACK"): //ignore this message, it's irrelevant + case "MESSAGE_ACK": //ignore this message, it's irrelevant break; + case "SESSIONS_REPLACE": // idk default: - if (UnknownMessageTypeReceived != null) - UnknownMessageTypeReceived(this, new UnknownMessageEventArgs { RawJson = message }); + UnknownMessageTypeReceived?.Invoke(this, new UnknownMessageEventArgs { RawJson = message }); break; } } - private void SendIdentifyPacket() + private async void SendIdentifyPacket() { string initJson = JsonConvert.SerializeObject(new { @@ -2096,13 +2151,24 @@ private void SendIdentifyPacket() v = 4, token = token, /*large_threshold = 50,*/ - properties = DiscordProperties + properties = DiscordProperties, + + large_threshold = 100, + synced_guilds = DiscordSyncedGuilds, + presence = new + { + status = "online", + since = 0, + afk = false, + game = "null", + }, + compress = false } }); DebugLogger.Log("Sending initJson ( " + initJson + " )"); - ws.Send(initJson); + await ws.SendMessage(initJson); } private void BeginHeartbeatTask() @@ -2127,36 +2193,59 @@ private void GuildMemberChunkEvents(JObject message) if (!message["d"]["members"].IsNullOrEmpty()) { DiscordServer inServer = ServersList.Find(x => x.ID == message["d"]["guild_id"].ToString()); - JArray membersAsArray = JArray.Parse(message["d"]["members"].ToString()); - foreach (var member in membersAsArray) + JArray membersAsArray = (JArray)message["d"]["members"]; + + Parallel.ForEach(membersAsArray, member => { - //if (GuildHasMemberWithID(inServer, member["user"]["id"].ToString())) - // continue; - DiscordMember _member = JsonConvert.DeserializeObject(member["user"].ToString()); - if (!member["user"]["roles"].IsNullOrEmpty()) + string memberId = (string)member["user"]["id"]; + + DiscordMember existingMember = inServer.GetMemberByKey((string)member["user"]["id"]); + + if (existingMember == null) { - JArray rollsArray = JArray.Parse(member["user"]["roles"].ToString()); - if (rollsArray.Count > 0) + existingMember = JsonConvert.DeserializeObject(member["user"].ToString()); + + if (!member["roles"].IsNullOrEmpty()) { - foreach (var rollID in rollsArray) - _member.Roles.Add(inServer.Roles.Find(x => x.ID == rollID.ToString())); + JArray rollsArray = (JArray)member["roles"]; + if (rollsArray.Count > 0) + { + foreach (var rollID in rollsArray) + { + existingMember.Roles.Add(inServer.Roles.Find(x => x.ID == rollID.ToString())); + } + } } + existingMember.Muted = member["mute"].ToObject(); + existingMember.Deaf = member["deaf"].ToObject(); + existingMember.Roles.Add(inServer.Roles.Find(x => x.Name == "@everyone")); + existingMember.Status = Status.Offline; + existingMember.parentclient = this; + existingMember.Parent = inServer; + inServer.AddMember(existingMember); + } + else + { + // does nothing, already in list } - _member.Muted = member["mute"].ToObject(); - _member.Deaf = member["deaf"].ToObject(); - _member.Roles.Add(inServer.Roles.Find(x => x.Name == "@everyone")); - _member.Status = Status.Offline; - _member.parentclient = this; - _member.Parent = inServer; - inServer.AddMember(_member); ///Check private channels - DiscordPrivateChannel _channel = PrivateChannels.Find(x => x.user_id == _member.ID); + DiscordPrivateChannel _channel = PrivateChannels.Find(x => x.user_id == existingMember.ID); if (_channel != null) { DebugLogger.Log("Found user for private channel!", MessageLevel.Debug); - _channel.Recipient = _member; + _channel.Recipient = existingMember; } + }); + // Debug.WriteLine("Loaded Member size: " + membersAsArray.Count + " Total size: " + inServer.Members.Count); + + if (membersAsArray.Count != 1000) // chunks of 1000 sent at once. + { + GuildMembersLoadedEventArgs?.Invoke(this, new DiscordGuildMembersLoadedEventArgs() + { + Server = inServer, + MemberSize = inServer.Members.Count, + }); } } } @@ -2168,8 +2257,7 @@ private void GuildMemberBanRemovedEvents(JObject message) e.Guild = ServersList.Find(x => x.ID == message["d"]["guild_id"].ToString()); e.MemberStub = JsonConvert.DeserializeObject(message["d"]["user"].ToString()); - if (BanRemoved != null) - BanRemoved(this, e); + BanRemoved?.Invoke(this, e); } private void GuildMemberBannedEvents(JObject message) @@ -2191,8 +2279,7 @@ private void GuildMemberBannedEvents(JObject message) e.MemberBanned = RemovedMembers.Find(x => x.ID == message["d"]["user"]["id"].ToString()); if (e.MemberBanned != null) { - if (GuildMemberBanned != null) - GuildMemberBanned(this, e); + GuildMemberBanned?.Invoke(this, e); } else { @@ -2209,7 +2296,8 @@ private void GuildMemberBannedEvents(JObject message) private void VoiceServerUpdateEvents(JObject message) { // TODO VoiceClient is null when disconnecting from voice - if (VoiceClient == null) { + if (VoiceClient == null) + { return; } VoiceClient.VoiceEndpoint = message["d"]["endpoint"].ToString(); @@ -2220,14 +2308,12 @@ private void VoiceServerUpdateEvents(JObject message) VoiceClient.PacketReceived += (sender, e) => { - if (AudioPacketReceived != null) - AudioPacketReceived(sender, e); + AudioPacketReceived?.Invoke(sender, e); }; VoiceClient.DebugMessageReceived += (sender, e) => { - if (VoiceClientDebugMessageReceived != null) - VoiceClientDebugMessageReceived(this, e); + VoiceClientDebugMessageReceived?.Invoke(this, e); }; ConnectToVoiceAsync(); @@ -2407,7 +2493,7 @@ public void EchoPacket(DiscordAudioPacket packet) /// The voice configuration to use. If null, default values will be used. /// Whether or not the client will connect muted. Defaults to false. /// Whether or not the client will connect deaf. Defaults to false. - public void ConnectToVoiceChannel(DiscordChannel channel, DiscordVoiceConfig voiceConfig = null, bool clientMuted = false, bool clientDeaf = false) + public async void ConnectToVoiceChannel(DiscordChannel channel, DiscordVoiceConfig voiceConfig = null, bool clientMuted = false, bool clientDeaf = false) { if (channel.Type != ChannelType.Voice) throw new InvalidOperationException($"Channel '{channel.ID}' is not a voice channel!"); @@ -2460,7 +2546,7 @@ public void ConnectToVoiceChannel(DiscordChannel channel, DiscordVoiceConfig voi } }); - ws.Send(joinVoicePayload); + await ws.SendMessage(joinVoicePayload); } /// @@ -2487,7 +2573,7 @@ public int ClearOfflineUsersFromServer(DiscordServer server) /// /// Also disposes /// - public void DisconnectFromVoice() + public async void DisconnectFromVoice() { string disconnectMessage = JsonConvert.SerializeObject(new { @@ -2508,13 +2594,15 @@ public void DisconnectFromVoice() VoiceClient = null; - ws.Send(disconnectMessage); + await ws.SendMessage(disconnectMessage); } catch { } } if (ws != null) - ws.Send(disconnectMessage); + { + await ws.SendMessage(disconnectMessage); + } VoiceClient = null; if (VoiceThread != null) VoiceThread.Abort(); @@ -2541,7 +2629,7 @@ private void GuildMemberUpdateEvents(JObject message) if (memberUpdated != null) { memberUpdated.Username = message["d"]["user"]["username"].ToString(); - if(message["d"]["nick"] != null) + if (message["d"]["nick"] != null) { if (message["d"]["nick"].ToString() == null) memberUpdated.Nickname = ""; //No nickname @@ -2553,7 +2641,7 @@ private void GuildMemberUpdateEvents(JObject message) memberUpdated.Avatar = message["d"]["user"]["avatar"].ToString(); memberUpdated.Discriminator = message["d"]["user"]["discriminator"].ToString(); memberUpdated.ID = message["d"]["user"]["id"].ToString(); - + foreach (var roles in message["d"]["roles"]) { memberUpdated.Roles.Add(server.Roles.Find(x => x.ID == roles.ToString())); @@ -2907,7 +2995,7 @@ private void GuildCreateEvents(JObject message) server.parentclient = this; server.ID = message["d"]["id"].ToString(); server.Name = message["d"]["name"].ToString(); - server.Members = new Dictionary(); + server.Members = new Dictionary(); server.Channels = new List(); server.Roles = new List(); foreach (var roll in message["d"]["roles"]) @@ -2959,7 +3047,7 @@ private void GuildCreateEvents(JObject message) foreach (var mbr in message["d"]["members"]) { DiscordMember member = JsonConvert.DeserializeObject(mbr["user"].ToString()); - if(mbr["nick"] != null) + if (mbr["nick"] != null) member.Nickname = mbr["nick"].ToString(); member.parentclient = this; @@ -2973,7 +3061,8 @@ private void GuildCreateEvents(JObject message) member.Roles.Add(server.Roles.Find(x => x.Name == "@everyone")); server.AddMember(member); } - foreach (var voiceStateJSON in message["d"]["voice_states"]) { + foreach (var voiceStateJSON in message["d"]["voice_states"]) + { DiscordVoiceState voiceState = JsonConvert.DeserializeObject(voiceStateJSON.ToString()); DiscordMember member = server.GetMemberByKey(voiceState.UserID); @@ -3079,6 +3168,7 @@ private void UserUpdateEvents(JObject message) //Update members foreach (var server in ServersList) { + foreach (var member in server.Members) { if (member.Value.ID == newMember.ID) @@ -3210,7 +3300,7 @@ private JObject ServerInfo(string channelOrServerId) private int HeartbeatInterval = 41250; private static DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); - private void KeepAlive() + private async void KeepAlive() { //string keepAliveJson = "{\"op\":" + Opcodes.HEARTBEAT + ", \"d\":" + Sequence + "}"; string keepAliveJson = JsonConvert.SerializeObject(new @@ -3220,7 +3310,7 @@ private void KeepAlive() }); if (ws != null) { - ws.Send(keepAliveJson); + await ws.SendMessage(keepAliveJson); KeepAliveSent?.Invoke(this, new DiscordKeepAliveSentEventArgs { SentAt = DateTime.Now, JsonSent = keepAliveJson }); } } @@ -3303,6 +3393,8 @@ public string SendLoginRequest() message += " Email was invalid: " + result["email"]; if (!result["password"].IsNullOrEmpty()) message += " password was invalid: " + result["password"]; + if (!result["captcha_key"].IsNullOrEmpty()) + message += " captcha required for this IP address: " + result["captcha_key"].ToString(); throw new DiscordLoginException(message); } diff --git a/.NET core/DiscordSharp/DiscordSharp.csproj b/.NET core/DiscordSharp/DiscordSharp.csproj new file mode 100644 index 0000000..c9e948e --- /dev/null +++ b/.NET core/DiscordSharp/DiscordSharp.csproj @@ -0,0 +1,22 @@ + + + + netcoreapp2.0 + + + + true + true + + + + true + + + + + + + + + diff --git a/DiscordSharp/Endpoints.cs b/.NET core/DiscordSharp/Endpoints.cs similarity index 100% rename from DiscordSharp/Endpoints.cs rename to .NET core/DiscordSharp/Endpoints.cs diff --git a/DiscordSharp/EpochTime.cs b/.NET core/DiscordSharp/EpochTime.cs similarity index 100% rename from DiscordSharp/EpochTime.cs rename to .NET core/DiscordSharp/EpochTime.cs diff --git a/DiscordSharp/Events/DiscordBanRemovedEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordBanRemovedEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordBanRemovedEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordBanRemovedEventArgs.cs diff --git a/DiscordSharp/Events/DiscordChannelCreateEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordChannelCreateEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordChannelCreateEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordChannelCreateEventArgs.cs diff --git a/DiscordSharp/Events/DiscordChannelDeleteEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordChannelDeleteEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordChannelDeleteEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordChannelDeleteEventArgs.cs diff --git a/DiscordSharp/Events/DiscordChannelUpdateEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordChannelUpdateEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordChannelUpdateEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordChannelUpdateEventArgs.cs diff --git a/DiscordSharp/Events/DiscordConnectEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordConnectEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordConnectEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordConnectEventArgs.cs diff --git a/DiscordSharp/Events/DiscordDebugMessagesEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordDebugMessagesEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordDebugMessagesEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordDebugMessagesEventArgs.cs diff --git a/DiscordSharp/Events/DiscordGuildBanEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordGuildBanEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordGuildBanEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordGuildBanEventArgs.cs diff --git a/DiscordSharp/Events/DiscordGuildCreateEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordGuildCreateEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordGuildCreateEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordGuildCreateEventArgs.cs diff --git a/DiscordSharp/Events/DiscordGuildDeleteEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordGuildDeleteEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordGuildDeleteEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordGuildDeleteEventArgs.cs diff --git a/DiscordSharp/Events/DiscordGuildMemberAddEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordGuildMemberAddEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordGuildMemberAddEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordGuildMemberAddEventArgs.cs diff --git a/DiscordSharp/Events/DiscordGuildMemberRemoved.cs b/.NET core/DiscordSharp/Events/DiscordGuildMemberRemoved.cs similarity index 100% rename from DiscordSharp/Events/DiscordGuildMemberRemoved.cs rename to .NET core/DiscordSharp/Events/DiscordGuildMemberRemoved.cs diff --git a/DiscordSharp/Events/DiscordGuildMemberUpdateEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordGuildMemberUpdateEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordGuildMemberUpdateEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordGuildMemberUpdateEventArgs.cs diff --git a/.NET core/DiscordSharp/Events/DiscordGuildMembersLoadedEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordGuildMembersLoadedEventArgs.cs new file mode 100644 index 0000000..d14cf2a --- /dev/null +++ b/.NET core/DiscordSharp/Events/DiscordGuildMembersLoadedEventArgs.cs @@ -0,0 +1,13 @@ +using DiscordSharp.Objects; +using System; +using System.Collections.Generic; +using System.Text; + +namespace DiscordSharp.Events +{ + public class DiscordGuildMembersLoadedEventArgs : EventArgs + { + public DiscordServer Server { get; internal set; } + public int MemberSize { get; internal set; } + } +} diff --git a/DiscordSharp/Events/DiscordGuildRoleDeleteEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordGuildRoleDeleteEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordGuildRoleDeleteEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordGuildRoleDeleteEventArgs.cs diff --git a/DiscordSharp/Events/DiscordGuildRoleUpdateEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordGuildRoleUpdateEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordGuildRoleUpdateEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordGuildRoleUpdateEventArgs.cs diff --git a/DiscordSharp/Events/DiscordKeepAliveSentEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordKeepAliveSentEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordKeepAliveSentEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordKeepAliveSentEventArgs.cs diff --git a/DiscordSharp/Events/DiscordLeftVoiceChannelEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordLeftVoiceChannelEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordLeftVoiceChannelEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordLeftVoiceChannelEventArgs.cs diff --git a/DiscordSharp/Events/DiscordMentionEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordMentionEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordMentionEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordMentionEventArgs.cs diff --git a/DiscordSharp/Events/DiscordMessageDeletedEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordMessageDeletedEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordMessageDeletedEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordMessageDeletedEventArgs.cs diff --git a/DiscordSharp/Events/DiscordMessageEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordMessageEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordMessageEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordMessageEventArgs.cs diff --git a/DiscordSharp/Events/DiscordPresenceUpdateEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordPresenceUpdateEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordPresenceUpdateEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordPresenceUpdateEventArgs.cs diff --git a/DiscordSharp/Events/DiscordPrivateChannelEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordPrivateChannelEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordPrivateChannelEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordPrivateChannelEventArgs.cs diff --git a/DiscordSharp/Events/DiscordPrivateMessageEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordPrivateMessageEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordPrivateMessageEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordPrivateMessageEventArgs.cs diff --git a/DiscordSharp/Events/DiscordServerUpdateEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordServerUpdateEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordServerUpdateEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordServerUpdateEventArgs.cs diff --git a/DiscordSharp/Events/DiscordSocketClosedEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordSocketClosedEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordSocketClosedEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordSocketClosedEventArgs.cs diff --git a/DiscordSharp/Events/DiscordTypingStartEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordTypingStartEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordTypingStartEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordTypingStartEventArgs.cs diff --git a/DiscordSharp/Events/DiscordURLUpdateEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordURLUpdateEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordURLUpdateEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordURLUpdateEventArgs.cs diff --git a/DiscordSharp/Events/DiscordUserUpdateEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordUserUpdateEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordUserUpdateEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordUserUpdateEventArgs.cs diff --git a/DiscordSharp/Events/DiscordVoiceStateUpdateEventArgs.cs b/.NET core/DiscordSharp/Events/DiscordVoiceStateUpdateEventArgs.cs similarity index 100% rename from DiscordSharp/Events/DiscordVoiceStateUpdateEventArgs.cs rename to .NET core/DiscordSharp/Events/DiscordVoiceStateUpdateEventArgs.cs diff --git a/DiscordSharp/Events/DiscordVoiceUserSpeaking.cs b/.NET core/DiscordSharp/Events/DiscordVoiceUserSpeaking.cs similarity index 100% rename from DiscordSharp/Events/DiscordVoiceUserSpeaking.cs rename to .NET core/DiscordSharp/Events/DiscordVoiceUserSpeaking.cs diff --git a/DiscordSharp/Events/UnknownMessageEventArgs.cs b/.NET core/DiscordSharp/Events/UnknownMessageEventArgs.cs similarity index 100% rename from DiscordSharp/Events/UnknownMessageEventArgs.cs rename to .NET core/DiscordSharp/Events/UnknownMessageEventArgs.cs diff --git a/DiscordSharp/Extensions.cs b/.NET core/DiscordSharp/Extensions.cs similarity index 100% rename from DiscordSharp/Extensions.cs rename to .NET core/DiscordSharp/Extensions.cs diff --git a/DiscordSharp/Logger.cs b/.NET core/DiscordSharp/Logger.cs similarity index 100% rename from DiscordSharp/Logger.cs rename to .NET core/DiscordSharp/Logger.cs diff --git a/DiscordSharp/Objects/DiscordChannel.cs b/.NET core/DiscordSharp/Objects/DiscordChannel.cs similarity index 100% rename from DiscordSharp/Objects/DiscordChannel.cs rename to .NET core/DiscordSharp/Objects/DiscordChannel.cs diff --git a/DiscordSharp/Objects/DiscordLoginException.cs b/.NET core/DiscordSharp/Objects/DiscordLoginException.cs similarity index 100% rename from DiscordSharp/Objects/DiscordLoginException.cs rename to .NET core/DiscordSharp/Objects/DiscordLoginException.cs diff --git a/DiscordSharp/Objects/DiscordLoginInformation.cs b/.NET core/DiscordSharp/Objects/DiscordLoginInformation.cs similarity index 100% rename from DiscordSharp/Objects/DiscordLoginInformation.cs rename to .NET core/DiscordSharp/Objects/DiscordLoginInformation.cs diff --git a/DiscordSharp/Objects/DiscordMember.cs b/.NET core/DiscordSharp/Objects/DiscordMember.cs similarity index 93% rename from DiscordSharp/Objects/DiscordMember.cs rename to .NET core/DiscordSharp/Objects/DiscordMember.cs index 1d95621..06d7262 100644 --- a/DiscordSharp/Objects/DiscordMember.cs +++ b/.NET core/DiscordSharp/Objects/DiscordMember.cs @@ -13,7 +13,10 @@ namespace DiscordSharp.Objects { public enum Status { - Online, Idle, Offline + Online, + Idle, + Offline, + DoNotDisturb } public class DiscordMember { @@ -52,12 +55,23 @@ Voice only internal void SetPresence(string status) { string checkAgainst = status.ToLower().Trim(); - if (checkAgainst == "online") - Status = Status.Online; - else if (checkAgainst == "idle") - Status = Status.Idle; - else - Status = Status.Offline; + switch (checkAgainst) + { + case "dnd": + Status = Status.DoNotDisturb; + break; + case "online": + Status = Status.Online; + break; + case "idle": + Status = Status.Idle; + break; + case "offline": + Status = Status.Offline; + break; + default: + throw new Exception("New presence status type found: " + status); + } } diff --git a/DiscordSharp/Objects/DiscordMessage.cs b/.NET core/DiscordSharp/Objects/DiscordMessage.cs similarity index 100% rename from DiscordSharp/Objects/DiscordMessage.cs rename to .NET core/DiscordSharp/Objects/DiscordMessage.cs diff --git a/DiscordSharp/Objects/DiscordPermission.cs b/.NET core/DiscordSharp/Objects/DiscordPermission.cs similarity index 100% rename from DiscordSharp/Objects/DiscordPermission.cs rename to .NET core/DiscordSharp/Objects/DiscordPermission.cs diff --git a/DiscordSharp/Objects/DiscordPermissionOverride.cs b/.NET core/DiscordSharp/Objects/DiscordPermissionOverride.cs similarity index 100% rename from DiscordSharp/Objects/DiscordPermissionOverride.cs rename to .NET core/DiscordSharp/Objects/DiscordPermissionOverride.cs diff --git a/DiscordSharp/Objects/DiscordRole.cs b/.NET core/DiscordSharp/Objects/DiscordRole.cs similarity index 100% rename from DiscordSharp/Objects/DiscordRole.cs rename to .NET core/DiscordSharp/Objects/DiscordRole.cs diff --git a/DiscordSharp/Objects/DiscordServer.cs b/.NET core/DiscordSharp/Objects/DiscordServer.cs similarity index 94% rename from DiscordSharp/Objects/DiscordServer.cs rename to .NET core/DiscordSharp/Objects/DiscordServer.cs index 74f5116..d54e0d9 100644 --- a/DiscordSharp/Objects/DiscordServer.cs +++ b/.NET core/DiscordSharp/Objects/DiscordServer.cs @@ -79,33 +79,34 @@ internal DiscordServer() Members = new Dictionary(); } - + internal void AddMember(DiscordMember member) { if (member == null) return; - if(Members.ContainsKey(member.ID)) //then replace + + lock (Members) { - Members.Remove(member.ID); + if (Members.ContainsKey(member.ID)) //then replace + Members.Remove(member.ID); + + Members.Add(member.ID, member); } - Members.Add(member.ID, member); } internal int ClearOfflineMembers() { - int count = 0; - foreach(var member in Members) - { - if (member.Value.Status == Status.Offline) - return count; - } - return count; + return Members.Count(mem => mem.Value.Status == Status.Offline); } internal bool RemoveMember(ID key) { - if(Members.ContainsKey(key)) + if (Members.ContainsKey(key)) { - Members.Remove(key); + lock (Members) + { + Members.Remove(key); + } + return true; } return false; } @@ -114,14 +115,11 @@ public DiscordMember GetMemberByKey(ID key) if (Unavailable) throw new Exception("Server is currently unavailable!"); - try - { - return Members.First(x => x.Key == key).Value; - } - catch + if (Members.ContainsKey(key)) { - return null; //because instead of just returning null by default, it has to do this shit. + return Members[key]; } + return null; } public DiscordMember GetMemberByUsername(string username, bool caseSensitive = false) { @@ -273,7 +271,8 @@ public DiscordChannel CreateChannel(string ChannelName, bool voice) var result = JObject.Parse(WebWrapper.Post(url, DiscordClient.token, reqJson)); if (result != null) { - DiscordChannel dc = new DiscordChannel { + DiscordChannel dc = new DiscordChannel + { Name = result["name"].ToString(), ID = result["id"].ToString(), Type = result["type"].ToObject(), diff --git a/DiscordSharp/Objects/DiscordUserInformation.cs b/.NET core/DiscordSharp/Objects/DiscordUserInformation.cs similarity index 100% rename from DiscordSharp/Objects/DiscordUserInformation.cs rename to .NET core/DiscordSharp/Objects/DiscordUserInformation.cs diff --git a/DiscordSharp/Objects/DiscordVoiceState.cs b/.NET core/DiscordSharp/Objects/DiscordVoiceState.cs similarity index 100% rename from DiscordSharp/Objects/DiscordVoiceState.cs rename to .NET core/DiscordSharp/Objects/DiscordVoiceState.cs diff --git a/DiscordSharp/Objects/RateLimitException.cs b/.NET core/DiscordSharp/Objects/RateLimitException.cs similarity index 100% rename from DiscordSharp/Objects/RateLimitException.cs rename to .NET core/DiscordSharp/Objects/RateLimitException.cs diff --git a/DiscordSharp/Opcodes.cs b/.NET core/DiscordSharp/Opcodes.cs similarity index 100% rename from DiscordSharp/Opcodes.cs rename to .NET core/DiscordSharp/Opcodes.cs diff --git a/.NET core/DiscordSharp/Sockets/BuiltIn/NetWebSocketWrapper.cs b/.NET core/DiscordSharp/Sockets/BuiltIn/NetWebSocketWrapper.cs new file mode 100644 index 0000000..6c71bd8 --- /dev/null +++ b/.NET core/DiscordSharp/Sockets/BuiltIn/NetWebSocketWrapper.cs @@ -0,0 +1,188 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.WebSockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace DiscordSharp.Sockets.BuiltIn +{ + public class NetWebSocketWrapper + { + private const int ReceiveChunkSize = 4096; + + private string _URL; + public string URL + { + get { return _URL; } + private set { } + } + + private readonly ClientWebSocket _ws; + private readonly Uri _uri; + private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); + private readonly CancellationToken _cancellationToken; + + /// + /// Create an instance + /// + /// + public NetWebSocketWrapper(string uri) + { + this._URL = uri; + + _ws = new ClientWebSocket(); + _ws.Options.KeepAliveInterval = TimeSpan.FromSeconds(20); + _uri = new Uri(uri); + _cancellationToken = _cancellationTokenSource.Token; + + //_ws.CloseStatusDescription + //_ws.CloseStatus.Value.ToString(); + } + + #region Public methods + public event EventHandler MessageReceived; + public event EventHandler SocketClosed; + public event EventHandler SocketError; + public event EventHandler SocketOpened; + + public bool IsAlive + { + get + { + return _ws != null; + } + } + + /// + /// Connects to the WebSocket server. + /// + public void Connect() + { + //await _ws.ConnectAsync(_uri, _cancellationToken); + _ws.ConnectAsync(_uri, _cancellationToken).Wait(); + + SocketOpened?.Invoke(this, null); + + StartListen(); + } + + /// + /// Close socket + /// + public void Close() + { + CallOnDisconnected("User requested to exit."); + } + + /// + /// Send a message to the WebSocket server. + /// + /// The message to send + /// success + public async Task SendMessage(string message) + { + byte[] messageBuffer = Encoding.UTF8.GetBytes(message); + return await SendMessage(messageBuffer); + } + + /// + /// Sends a byte array to the connected socket + /// + /// + /// success + public async Task SendMessage(byte[] buffer) + { + if (_ws.State != WebSocketState.Open) + { + throw new Exception("Connection is not open."); + } + try + { + await _ws.SendAsync(new ArraySegment(buffer), WebSocketMessageType.Text, true, CancellationToken.None); + return true; + } + catch (Exception exp) + { + CallOnDisconnected(exp.Message); + } + return false; + } + #endregion + + private async void StartListen() + { + try + { + while (_ws != null && _ws.State == WebSocketState.Open) + { + byte[] Sharedbuffer = new byte[ReceiveChunkSize]; + + + using (var ms = new MemoryStream()) // auto release memory + { + WebSocketReceiveResult res; + do + { + res = await _ws.ReceiveAsync(Sharedbuffer, CancellationToken.None); + if (res.MessageType == WebSocketMessageType.Close) + { + CallOnDisconnected(null); + return; + } + ms.Write(Sharedbuffer, 0, res.Count); + // ms.Write(segment.Array, segment.Offset, res.Count); + } + while (!res.EndOfMessage); + + ms.Seek(0, SeekOrigin.Begin); + + // Return data + byte[] returnBuffer = new byte[ms.Length]; + Buffer.BlockCopy(ms.ToArray(), 0, returnBuffer, 0, (int)ms.Length); + + string msg = Encoding.UTF8.GetString(returnBuffer); + + // Fires the return packet in a new thread + ThreadPool.QueueUserWorkItem(state => + { + SocketMessageEventArgs args = new SocketMessageEventArgs + { + Message = msg + }; + MessageReceived?.Invoke(this, args); + }); + } + } + } + catch (Exception ex) + { + Console.WriteLine(ex.StackTrace); + CallOnDisconnected(ex.Message); + } + finally + { + _ws.Dispose(); + } + } + + private void CallOnDisconnected(string messageOverride) + { + try + { + _ws.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None).Wait(); + } + catch { } + + SocketClosedEventArgs args = new SocketClosedEventArgs + { + Reason = messageOverride != null ? messageOverride : _ws.CloseStatusDescription, + WasClean = false, + Code = _ws.CloseStatus != null ? (int)_ws.CloseStatus.Value : -1 + }; + SocketClosed?.Invoke(this, args); + } + } +} diff --git a/.NET core/DiscordSharp/Sockets/IDiscordWebSocket.cs b/.NET core/DiscordSharp/Sockets/IDiscordWebSocket.cs new file mode 100644 index 0000000..95bfc71 --- /dev/null +++ b/.NET core/DiscordSharp/Sockets/IDiscordWebSocket.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DiscordSharp.Sockets +{ + public class SocketMessageEventArgs : EventArgs + { + public string Message { get; internal set; } + } + + public class SocketClosedEventArgs : EventArgs + { + public string Reason { get; internal set; } + public int Code { get; internal set; } + public bool WasClean { get; internal set; } + } + + public class SocketErrorEventArgs : EventArgs + { + public Exception Exception { get; internal set; } + public string Message { get; internal set; } + } + + +} diff --git a/DiscordSharp/Utils.cs b/.NET core/DiscordSharp/Utils.cs similarity index 100% rename from DiscordSharp/Utils.cs rename to .NET core/DiscordSharp/Utils.cs diff --git a/DiscordSharp/Voice/DiscordAudioPacket.cs b/.NET core/DiscordSharp/Voice/DiscordAudioPacket.cs similarity index 100% rename from DiscordSharp/Voice/DiscordAudioPacket.cs rename to .NET core/DiscordSharp/Voice/DiscordAudioPacket.cs diff --git a/.NET core/DiscordSharp/Voice/DiscordVoiceClient.cs b/.NET core/DiscordSharp/Voice/DiscordVoiceClient.cs new file mode 100644 index 0000000..50b3660 --- /dev/null +++ b/.NET core/DiscordSharp/Voice/DiscordVoiceClient.cs @@ -0,0 +1,969 @@ +using DiscordSharp.Events; +using DiscordSharp.Objects; +using DiscordSharp.Voice; +using Microsoft.Win32.SafeHandles; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Net; +using System.Net.Sockets; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; +using WebSocket4Net; +#if NETFX4_5 +using ws4n.WebSocket4Net; +using System.Collections.Concurrent; +#else +using CONCURRENT = System.Collections.Concurrent; +#endif + +/** + This file contains the methods necessary for creating a Discord voice connection. + + To any future library developers looking to implement voice, this is how the basic recipe for voice communication goes with Discord. + + Ingredients Needed: + 1. A decent UdpClient + 2. A websocket that doesn't suck. (different from your main one) + 3. An understanding of bitshifting. + + To begin the voice connection: + 1. On your main websocket, send json with opcode 4, the guild_id, and channel_id, and whether or not you want your client to muted/deaf. + 2. After that, you will get a websocket message with t = "VOICE_SERVER_UPDATE". + 2a. The json you receive will contain some IMPORTANT information including voice endpoint (for socket) and a token you will need. + 3. Now, you can initiate your voice client. + 4. Point your websocket client to the given endpoint and upon connection, send opcode 0 with the server ID, channel ID, your client ID, and that token you got prior. + 5. Opcode 2 gives you various parameters for your voice connection. + 5a. ssrc is basically your voice client ID. You will need it for your packet. It differentiates between users. + 5b. Guess what port is for. + 5c. (I believe) modes is for voice encryption. + 5d. heartbeat_interval is very important. The voice connection is extremely finnicky with its keepalives so **DONT HARDCODE THIS VALUE**. It's usually 5500 ms. + 5e. After opcode 2, you can begin your websocket keepalive. + 6. Now, you should be safe to begin your UDP connection. Point it to the endpoint you used to connect to voice initially BUT do **NOT** use the default port! Use the port that is given to you in opcode 2. + 6a. Also, don't include the wss:// + 7. Once connected, send a 70 byte packet containing your ssrc as bigendian for the first 4 bytes. + 8. Your response should be a packet. This packet contains your IP address and port you need. Please use the IP from this packet. + 8a. Quoth thy wise Danny: "the ip is ascii starting at the 4th byte and ending at the first null" + 8b. the port is a little endian unsigned short in the last two bytes + yes, this is different endianness from everything else + 9. You will then send opcode 1 with your protocol (more than likely udp), your IP from the packet, the port from the packet, and a mode. More than likely "plain" + 10. Finally, once you receive opcode 4, you may send the "speaking" json (opcode 5, speaking = true/false, delay = 0). At this point, you are fully connected and you may begin any other threads/keepalives. +*/ + +namespace DiscordSharp +{ + internal class VoiceConnectionParameters + { + [JsonProperty("ssrc")] + public int ssrc { get; internal set; } + [JsonProperty("port")] + public int port { get; internal set; } + [JsonProperty("modes")] + public string[] modes { get; internal set; } + [JsonProperty("heartbeat_interval")] + public int heartbeat_interval { get; internal set; } + } + + internal struct DiscordIpPort + { + public IPAddress Address; + public int port; + } + + public class DiscordAudioPacketEventArgs : EventArgs + { + //public DiscordAudioPacket Packet { get; internal set; } + public byte[] OpusAudio { get; internal set; } + public int OpusAudioLength { get; internal set; } + public DiscordChannel Channel { get; internal set; } + public DiscordMember FromUser { get; internal set; } + } + + public class DiscordVoiceConfig + { + internal int SampleRate { get; set; } = 48000; //discord default + /// + /// The amount of channels you wish to send over the network. + /// Use 2 for stereo. Stereo will require more bandwidth. + /// + public int Channels { get; set; } = 1; + + /// + /// The frame length, in ms, of audio you'll be sending at one time. + /// As a rule of thumb, you generally want to set it to something above your current Discord ping. + /// + public int FrameLengthMs { get; set; } = 60; + + /// + /// The voice client now auto-configures this based on the channel. + /// + [Obsolete] + public int? Bitrate { get; set; } = null; + + /// + /// The mode the Opus encoder will use. + /// MusicOrMixed is generally the best. + /// + public OpusApplication OpusMode { get; set; } = OpusApplication.MusicOrMixed; + + /// + /// If true, the voice client will only send voice and will not receive it. + /// + public bool SendOnly { get; set; } = true; + + /// + /// The blocksize of PCM data you should be reading and piping into DiscordSharp. + /// + public int PCMBlockSize + { + get + { + return ((SampleRate / 1000) * 2 * Channels * FrameLengthMs); + } + } + } + + public class DiscordVoiceClient : IDisposable + { + private DiscordClient _parent; + + public bool Connected { get; internal set; } + public string SessionID { get; internal set; } + public string VoiceEndpoint { get; internal set; } + public string Token { get; internal set; } + public DiscordChannel Channel { get; internal set; } + public DiscordServer Guild { get; internal set; } + public DiscordMember Me { get; internal set; } + private DiscordMember LastSpoken { get; set; } + private UdpClient _udp = new UdpClient(); + private VoiceConnectionParameters Params { get; set; } + private Logger VoiceDebugLogger = new Logger(); + private WebSocket VoiceWebSocket; + private OpusEncoder mainOpusEncoder; + private CancellationTokenSource globalTaskSource = new CancellationTokenSource(); + //private CONCURRENT.ConcurrentQueue voiceToSend = new CONCURRENT.ConcurrentConcurrentQueue();\ +#if NETFX4_5 + private ConcurrentQueue voiceToSend = new ConcurrentQueue(); +#else + private CONCURRENT.ConcurrentQueue voiceToSend = new CONCURRENT.ConcurrentQueue(); +#endif + private List MembersInChannel = new List(); + private Dictionary SsrcDictionary = new Dictionary(); + private string encryptionMode = "xsalsa20_poly1305"; + private byte[] __secretKey; + private Thread VoiceSendThread, VoiceReceiveThread, UDPKeepAliveThread, WebsocketKeepAliveThread; + + private IPEndPoint udpEndpoint; + + public OpusDecoder Decoder { get; private set; } + public DiscordVoiceConfig VoiceConfig { get; internal set; } + + #region Events + internal event EventHandler DebugMessageReceived; + internal event EventHandler Disposed; + internal event EventHandler UserSpeaking; + internal event EventHandler PacketReceived; + internal event EventHandler ErrorReceived; + internal event EventHandler VoiceConnectionComplete; + internal event EventHandler QueueEmpty; +#endregion + +#region voice sending stuff + /// + /// The length, in ms, of audio for DiscordSharp to send. By default, 20. + /// + static int msToSend = 20; + + /// + /// An signed short designating the sequence of the audio being sent. + /// + internal ushort ___sequence = 0; + + /// + /// Unsigned int designating the timestamp offset of the audio being sent. + /// + internal uint ___timestamp = 0; +#endregion + + public Logger GetDebugLogger => VoiceDebugLogger; + + public DiscordVoiceClient(DiscordClient parentClient) + { + _parent = parentClient; + VoiceConfig = new DiscordVoiceConfig(); + InitializeOpusEncoder(); + } + + public DiscordVoiceClient(DiscordClient parentClient, DiscordVoiceConfig config) + { + _parent = parentClient; + VoiceConfig = config; + InitializeOpusEncoder(); + } + + public DiscordVoiceClient(DiscordClient parentClient, DiscordVoiceConfig config, DiscordChannel channel) + { + _parent = parentClient; + VoiceConfig = config; + Channel = channel; + InitializeOpusEncoder(); + } + + internal void InitializeOpusEncoder() + { + if (Channel != null && Channel.Type == ChannelType.Voice) + { + if (Channel.Bitrate > 0) + { + mainOpusEncoder = new OpusEncoder(VoiceConfig.SampleRate, + VoiceConfig.Channels, + VoiceConfig.FrameLengthMs, + (Channel.Bitrate / 1000), + VoiceConfig.OpusMode); + } + else + { + mainOpusEncoder = new OpusEncoder(VoiceConfig.SampleRate, + VoiceConfig.Channels, + VoiceConfig.FrameLengthMs, + null, + VoiceConfig.OpusMode); + } + + mainOpusEncoder.SetForwardErrorCorrection(true); + msToSend = VoiceConfig.FrameLengthMs; + } + if(!VoiceConfig.SendOnly) + InitializeOpusDecoder(); + } + + private void InitializeOpusDecoder() + { + if(Channel != null && Channel.Type == ChannelType.Voice) + { + Decoder = new OpusDecoder(VoiceConfig.SampleRate, VoiceConfig.Channels, VoiceConfig.FrameLengthMs); + } + } + + /// + /// Begins the voice client connection. + /// + public void Initiate() + { + if(Me == null) + { + if (_parent != null) + { + Me = _parent.Me; + } + else + throw new NullReferenceException("VoiceClient's main client reference was null!"); + } + + MembersInChannel.Add(Me); + + VoiceDebugLogger.LogMessageReceived += (sender, e) => + { + if (DebugMessageReceived != null) + DebugMessageReceived(this, e); + }; + + VoiceWebSocket = new WebSocket(VoiceEndpoint.StartsWith("wss://") ? VoiceEndpoint.Replace(":80", "") : + "wss://" + VoiceEndpoint.Replace(":80", "")); + VoiceWebSocket.EnableAutoSendPing = false; + + //VoiceWebSocket.AllowUnstrustedCertificate = true; // TODO + VoiceWebSocket.NoDelay = true; + VoiceWebSocket.Closed += VoiceWebSocket_OnClose; + VoiceWebSocket.Error += VoiceWebSocket_OnError; + + VoiceWebSocket.MessageReceived += (s, e) => + { + try + { + VoiceWebSocket_OnMessage(s, e); + } + catch(Exception ex) + { + VoiceDebugLogger.Log($"Exception while awaiting OnMessage?!\n\tMessage: {ex.Message}\n\tStack: {ex.StackTrace}", MessageLevel.Critical); + } + }; + VoiceWebSocket.Opened += (sender, e) => + { + string initMsg = JsonConvert.SerializeObject(new + { + op = 0, + d = new + { + server_id = Guild.ID, + user_id = Me.ID, + session_id = SessionID, + token = Token + } + }); + + VoiceDebugLogger.Log("VoiceWebSocket opened, sending initial json. ( " + initMsg + ") "); + + VoiceWebSocket.Send(initMsg); + }; + + VoiceWebSocket.Open(); + } + +#pragma warning disable 4014 //stupid await warnings + private void VoiceWebSocket_OnMessage(object sender, MessageReceivedEventArgs e) + { + JObject message = JObject.Parse(e.Message); + switch (int.Parse(message["op"].ToString())) + { + case 2: + //VoiceDebugLogger.Log(e.Message); + OpCode2(message); + //ok, now that we have opcode 2 we have to send a packet and configure the UDP + InitialUDPConnection(); + break; + case 3: + VoiceDebugLogger.Log("KeepAlive echoed back successfully!", MessageLevel.Unecessary); + break; + case 4: //you get your secret key from here + //post initializing the UDP client, we will receive opcode 4 and will now do the final connection steps + OpCode4(message); + //if (!VoiceConfig.SendOnly) + DoUDPKeepAlive(globalTaskSource.Token); + SendVoiceTask(globalTaskSource.Token); + if (!VoiceConfig.SendOnly) + ReceiveVoiceTask(globalTaskSource.Token); + SetSpeaking(true); + if (VoiceConnectionComplete != null) + VoiceConnectionComplete(this, new EventArgs()); + break; + case 5: //User speaking + //VoiceDebugLogger.Log(e.Message); + OpCode5(message); + break; + } + } +#pragma warning restore 4014 //stupid await warnings + +#region Websocket Opcode Events/other misc events + internal void MemberRemoved(DiscordMember removed) + { + if (MembersInChannel.Contains(removed)) + { + MembersInChannel.Remove(removed); + VoiceDebugLogger.Log($"User {removed.Username} ({removed.ID}) left the client's current connected voice channel."); + } + } + internal void MemberAdded(DiscordMember added) + { + if(added.Parent == Guild) + { + if(added.CurrentVoiceChannel == Channel) + { + if (MembersInChannel.Contains(added)) + MembersInChannel.Remove(added); + MembersInChannel.Add(added); + VoiceDebugLogger.Log($"User {added.Username} ({added.ID}) joined the client's current connected voice channel."); + } + } + } + private void OpCode5(JObject message) + { + DiscordVoiceUserSpeakingEventArgs e = new DiscordVoiceUserSpeakingEventArgs(); + e.Channel = Channel; + e.UserSpeaking = Guild.GetMemberByKey(message["d"]["user_id"].ToString()); + e.Speaking = message["d"]["speaking"].ToObject(); + e.Ssrc = message["d"]["ssrc"].ToObject(); + + if(e.UserSpeaking != null) + { + if (!SsrcDictionary.ContainsKey(e.UserSpeaking)) + SsrcDictionary.Add(e.UserSpeaking, e.Ssrc); + } + + LastSpoken = e.UserSpeaking; + + if (UserSpeaking != null) + UserSpeaking(this, e); + } + + private void OpCode4(JObject message) + { + __secretKey = message["d"]["secret_key"].ToObject(); + string speakingJson = JsonConvert.SerializeObject(new + { + op = 5, + d = new + { + speaking = true, + delay = 0 + } + }); + VoiceDebugLogger.Log("Sending initial speaking json..( " + speakingJson + " )"); + VoiceWebSocket.Send(speakingJson); + //we are officially connected!!! + Connected = true; + } + +#pragma warning disable 4014 + private void OpCode2(JObject message) + { + Params = JsonConvert.DeserializeObject(message["d"].ToString()); + SsrcDictionary.Add(Me, Params.ssrc); + for (int i = 0; i < Params.modes.Length; i++) + { + if (!Params.modes[i].ToLower().Contains("plain")) + { + encryptionMode = Params.modes[i]; + break; + } + } + //SendWebSocketKeepalive(); + DoWebSocketKeepAlive(globalTaskSource.Token); + } +#pragma warning restore 4014 + + private void VoiceWebSocket_OnError(object sender, EventArgs e) + { + VoiceDebugLogger.Log("Error in VoiceWebSocket.", MessageLevel.Critical); + ErrorReceived?.Invoke(this, new EventArgs()); + + //Won't worror about on error for now + } + + private void VoiceWebSocket_OnClose(object sender, EventArgs e) + { + VoiceDebugLogger.Log($"VoiceWebSocket was closed.", MessageLevel.Critical); + ErrorReceived?.Invoke(this, new EventArgs()); + + Dispose(); + } +#endregion + + private bool QueueEmptyEventTriggered = false; +#region Internal Voice Methods +#pragma warning disable 4014 + private void SendVoiceTask(CancellationToken token) + { + VoiceSendThread = new Thread(() => + { + while (!token.IsCancellationRequested) + { + if (!voiceToSend.IsEmpty) + { + QueueEmptyEventTriggered = false; + try + { + SendVoiceAsync(token); + } + catch (Exception ex) + { + VoiceDebugLogger.Log(ex.Message, MessageLevel.Error); + } + } + else + { +#if NETFX4_5 + //await Task.Delay(1000).ConfigureAwait(false); + Thread.Sleep(1000); +#else + Thread.Sleep(1000); +#endif + } + if (___sequence > 0 || ___timestamp > 0) + { + if (voiceToSend.IsEmpty) + { + //reset these + ___sequence = 0; + ___timestamp = 0; + if (!QueueEmptyEventTriggered) + { + QueueEmpty?.Invoke(this, new EventArgs()); + QueueEmptyEventTriggered = true; + } + } + } + } + }); + VoiceSendThread.Start(); + } +#pragma warning disable 4014 + private Task ReceiveVoiceTask(CancellationToken token) + { + VoiceDebugLogger.Log("Setting up for voice receive."); +#if NETFX4_5 + return Task.Run(async () => +#else + return Task.Factory.StartNew(async () => +#endif + { + while(!token.IsCancellationRequested) + { + if (_udp.Available > 0) + { + try + { + await DoReceiveVoice().ConfigureAwait(false); + } + catch (Exception ex) + { + VoiceDebugLogger.Log($"Exception in receive loop: {ex.Message}\n\t{ex.StackTrace}", MessageLevel.Error); + } + } + } + }, token); + } + + private async Task DoReceiveVoice() + { + _udp.DontFragment = false; + if (_udp.Available > 0) + { + //the packet received, the 4000 size buffer for decoding, the nonce header for encryption and the decrypted/decoded result :) + byte[] packet, decodingBuffer = null, nonce = null, result; + //UdpReceiveResult receivedResult = await _udp.ReceiveAsync().ConfigureAwait(false); + packet = _udp.Receive(ref udpEndpoint); + int packetLength, resultOffset, resultLength; + decodingBuffer = new byte[4000]; + nonce = new byte[24]; + packetLength = packet.Length; + + if (packet.Length > 0) + { + if (packetLength < 12) return; //irrelevant packet + if (packet[0] != 0x80) return; //flags + if (packet[1] != 0x78) return; //payload type. you know, from before. + + ushort sequenceNumber = (ushort)((packet[2] << 8) | packet[3] << 0); + uint timDocuestamp = (uint)((packet[4] << 24) | packet[5] << 16 | packet[6] << 8 | packet[7] << 0); + uint ssrc = (uint)((packet[8] << 24) | (packet[9] << 16) | (packet[10] << 8) | (packet[11] << 0)); + + //encryption is enabled by default + if (packetLength < 28) return; //irrelevant packet + + Buffer.BlockCopy(packet, 0, nonce, 0, 12); //copy nonce + var length = Convert.ToUInt64(packetLength - 12); + int returnValue = SecretBox.Decrypt(packet, 12, length, decodingBuffer, nonce, __secretKey); + if (returnValue != 0) + return; + result = decodingBuffer; + resultOffset = 0; resultLength = packetLength - 28; + + if (SsrcDictionary.ContainsValue((int)ssrc)) + { + if (PacketReceived != null) + { + PacketReceived(this, new DiscordAudioPacketEventArgs + { + Channel = this.Channel, + FromUser = GetUserBySsrc(ssrc), + OpusAudio = result, + OpusAudioLength = resultLength + }); + } + } + + } + } + } + + private DiscordMember GetUserBySsrc(uint ssrc) + { + foreach (var user in SsrcDictionary) + if (user.Value == ssrc) + return user.Key; + + return null; + } + +#pragma warning restore 4014 + private void SendVoiceAsync(CancellationToken cancelToken) + { + byte[] opusAudio; //pcm data + voiceToSend.TryDequeue(out opusAudio); + if (opusAudio != null) + { + Stopwatch timeToSend = Stopwatch.StartNew(); + + byte[] fullVoicePacket = new byte[4000 + 12 + 16]; + byte[] nonce = new byte[24]; + + fullVoicePacket[0] = (byte)0x80; //flags + fullVoicePacket[1] = (byte)0x78; //flags + + fullVoicePacket[8] = (byte)((Params.ssrc >> 24) & 0xFF); //ssrc + fullVoicePacket[9] = (byte)((Params.ssrc >> 16) & 0xFF); //ssrc + fullVoicePacket[10] = (byte)((Params.ssrc >> 8) & 0xFF); //ssrc + fullVoicePacket[11] = (byte)((Params.ssrc >> 0) & 0xFF); //ssrc + + //byte[] opusAudio = new byte[queuedOpus.Length - 4]; + //Buffer.BlockCopy(queuedOpus, 0, opusAudio, 0, opusAudio.Length); + //int encodedLength = mainOpusEncoder.EncodeFrame(voiceToEncode, 0, opusAudio); + + int encodedLength = BitConverter.ToInt32(opusAudio, opusAudio.Length - 4); + + int dataSent = 0; + + //actual sending + { + ___sequence = unchecked(___sequence++); + //sequence big endian + fullVoicePacket[2] = (byte)((___sequence >> 8)); + fullVoicePacket[3] = (byte)((___sequence >> 0) & 0xFF); + + //timestamp big endian + fullVoicePacket[4] = (byte)((___timestamp >> 24) & 0xFF); + fullVoicePacket[5] = (byte)((___timestamp >> 16) & 0xFF); + fullVoicePacket[6] = (byte)((___timestamp >> 8)); + fullVoicePacket[7] = (byte)((___timestamp >> 0) & 0xFF); + + Buffer.BlockCopy(fullVoicePacket, 0, nonce, 0, 12); //copy header into nonce + + //Buffer.BlockCopy(rtpPacket, 2, nonce, 2, 6); //copy 6 bytes for nonce + int returnVal = SecretBox.Encrypt(opusAudio, encodedLength, fullVoicePacket, 12, nonce, __secretKey); + if (returnVal != 0) + return; + if (opusAudio == null) + throw new ArgumentNullException("opusAudio"); + + int maxSize = encodedLength; + int rtpPacketLength = encodedLength + 12 + 16; + +#if NETFX4_5 + //dataSent = _udp.SendAsync(fullVoicePacket, encodedLength + 12 + 16).Result; + dataSent = _udp.Send(fullVoicePacket, encodedLength + 12 + 16); +#else + dataSent = _udp.Send(fullVoicePacket, rtpPacketLength); +#endif + + ___timestamp = unchecked(___timestamp + (uint)((opusAudio.Length - 4) / 2)); + } + + timeToSend.Stop(); //stop after completely sending + + //Compensate for however long it took to sent. + if (timeToSend.ElapsedMilliseconds > 0) + { + //long timeToWait = (msToSend * TimeSpan.TicksPerMillisecond) - (timeToSend.ElapsedMilliseconds * TimeSpan.TicksPerMillisecond); + //long timeToWait = (long)(msToSend * TimeSpan.TicksPerMillisecond * 0.80) - (timeToSend.ElapsedMilliseconds * TimeSpan.TicksPerMillisecond); + if (timeToSend.ElapsedMilliseconds > 0) //if it's negative then don't bother waiting + { + //Thread.Sleep((int)(msToSend - timeToSend.ElapsedMilliseconds)); + Thread.Sleep((int)Math.Floor(msToSend * 0.80)); + } + } + else + { + Thread.Sleep(msToSend); + } + + VoiceDebugLogger.LogAsync("Sent " + dataSent + " bytes of Opus audio", MessageLevel.Unecessary); + } + } + + private void DoWebSocketKeepAlive(CancellationToken token) + { + WebsocketKeepAliveThread = new Thread(() => + { + try + { + while (VoiceWebSocket.State == WebSocketState.Open && !token.IsCancellationRequested) + { + if (VoiceWebSocket != null) + { + if (VoiceWebSocket.State == WebSocketState.Open) + { + string keepAliveJson = JsonConvert.SerializeObject(new + { + op = 3, + d = EpochTime.GetMilliseconds() + }); + VoiceDebugLogger.Log("Sending voice keepalive ( " + keepAliveJson + " ) ", MessageLevel.Unecessary); + VoiceWebSocket.Send(keepAliveJson); + Thread.Sleep(Params.heartbeat_interval); + } + } + } + } + catch (NullReferenceException) { } + }); + WebsocketKeepAliveThread.Start(); + } + + private void DoUDPKeepAlive(CancellationToken token) + { + + UDPKeepAliveThread = new Thread(() => + { + byte[] keepAlive = new byte[5]; + keepAlive[0] = (byte)0xC9; + try + { + long seq = 0; + while (VoiceWebSocket.State == WebSocketState.Open && !token.IsCancellationRequested) + { + if (token.IsCancellationRequested) + break; + keepAlive[1] = (byte)((___sequence >> 24) & 0xFF); + keepAlive[2] = (byte)((___sequence >> 16) & 0xFF); + keepAlive[3] = (byte)((___sequence >> 8) & 0xFF); + keepAlive[4] = (byte)((___sequence >> 0) & 0xFF); + _udp.Send(keepAlive, keepAlive.Length); + VoiceDebugLogger.Log("Sent UDP keepalive.", MessageLevel.Unecessary); + Thread.Sleep(5 * 1000); + } + } + catch (ObjectDisposedException) + {/*cancel token disposed*/} + catch (NullReferenceException) + {/*disposed*/} + catch (Exception ex) + { + VoiceDebugLogger.Log($"Error sending UDP keepalive\n\t{ex.Message}\n\t{ex.StackTrace}", MessageLevel.Error); + } + }); + UDPKeepAliveThread.Start(); + } + private async Task InitialUDPConnection() + { + try + { + _udp = new UdpClient(Params.port); //passes in proper port + //_udp. + _udp.DontFragment = false; + _udp.Connect(VoiceEndpoint.Replace(":80", ""), Params.port); + + VoiceDebugLogger.Log($"Initialized UDP Client at {VoiceEndpoint.Replace(":80", "")}:{Params.port}"); + + udpEndpoint = new IPEndPoint(Dns.GetHostAddresses(VoiceEndpoint.Replace(":80", ""))[0], 80); + + + byte[] packet = new byte[70]; //the initial packet + packet[0] = (byte)((Params.ssrc >> 24) & 0xFF); + packet[1] = (byte)((Params.ssrc >> 16) & 0xFF); + packet[2] = (byte)((Params.ssrc >> 8) & 0xFF); + packet[3] = (byte)((Params.ssrc >> 0) & 0xFF); + +#if NETFX4_5 + await _udp.SendAsync(packet, packet.Length).ConfigureAwait(false); //sends this initial packet. + VoiceDebugLogger.Log("Sent ssrc packet."); + + UdpReceiveResult resultingMessage = await _udp.ReceiveAsync().ConfigureAwait(false); //receive a response packet + Console.WriteLine($"Receiving"); +#else + _udp.Send(packet, packet.Length, udpEndpoint); + VoiceDebugLogger.Log("Sent ssrc packet."); + + byte[] resultingMessage = _udp.Receive(ref udpEndpoint); +#endif + +#if NETFX4_5 + if (resultingMessage != null && resultingMessage.Buffer.Length > 0) +#else + if(resultingMessage != null && resultingMessage.Length > 0) +#endif + { + VoiceDebugLogger.Log("Received IP packet, reading.."); +#if NETFX4_5 + await SendIPOverUDP(GetIPAndPortFromPacket(resultingMessage.Buffer)).ConfigureAwait(false); +#else + var ipAndPort = GetIPAndPortFromPacket(resultingMessage); + udpEndpoint = new IPEndPoint(ipAndPort.Address, ipAndPort.port); + await SendIPOverUDP(ipAndPort).ConfigureAwait(false); +#endif + } + else + VoiceDebugLogger.Log("No IP packet received.", MessageLevel.Critical); + } + catch (Exception ex) + { + VoiceDebugLogger.Log("UDP Client Error: " + ex.Message, MessageLevel.Critical); + } + } + /// + /// Sends our IP over UDP for Discord's voice server to process. Also sends op 1 + /// + /// The byte[] returned after sending your ssrc. + /// + private async Task SendIPOverUDP(DiscordIpPort ipPort) + { + string msg = JsonConvert.SerializeObject(new + { + op = 1, + d = new + { + protocol = "udp", + data = new + { + address = ipPort.Address.ToString(), + port = ipPort.port, + mode = encryptionMode + } + } + }); + VoiceDebugLogger.Log("Sending our IP over WebSocket ( " + msg.ToString() + " ) "); + VoiceWebSocket.Send(msg); + //await Task.Run(() => VoiceWebSocket.Send(msg)).ConfigureAwait(false); //idk lets try it + } + + private DiscordIpPort GetIPAndPortFromPacket(byte[] packet) + { + DiscordIpPort returnVal = new DiscordIpPort(); + //quoth thy danny + //#the ip is ascii starting at the 4th byte and ending at the first null + int startingIPIndex = 4; + int endingIPIndex = 4; + for (int i = startingIPIndex; i < packet.Length; i++) + { + if (packet[i] != (byte)0) + endingIPIndex++; + else + break; + } + + byte[] ipArray = new byte[endingIPIndex - startingIPIndex]; + Buffer.BlockCopy(packet, startingIPIndex, ipArray, 0, ipArray.Length); + //quoth thy wise danny part two: + //# the port is a little endian unsigned short in the last two bytes + //# yes, this is different endianness from everything else + int port = packet[packet.Length - 2] | packet[packet.Length - 1] << 8; + + returnVal.Address = IPAddress.Parse(System.Text.Encoding.ASCII.GetString(ipArray)); + returnVal.port = port; + + VoiceDebugLogger.Log($"Our IP is {returnVal.Address} and we're using port {returnVal.port}."); + return returnVal; + } +#endregion + +#region Public Methods + /// + /// Enqueues audio to be sent through the UDP client. + /// + /// PCM audio data. + public void SendVoice(byte[] voice) + { + byte[] opusAudio = new byte[voice.Length + 4]; + int encodedLength = mainOpusEncoder.EncodeFrame(voice, 0, opusAudio); + + byte[] len = BitConverter.GetBytes(encodedLength); + opusAudio[voice.Length] = len[0]; + opusAudio[voice.Length + 1] = len[1]; + opusAudio[voice.Length + 2] = len[2]; + opusAudio[voice.Length + 3] = len[3]; + + voiceToSend.Enqueue(opusAudio); + } + + /// + /// Clears the voice queue thus stopping the audio. + /// + public void ClearVoiceQueue() + { + byte[] ignored; + while (voiceToSend.TryDequeue(out ignored)) ; + } + + /// + /// Echos a given DiscordAudioPacket. + /// + /// + /// + public async Task EchoPacket(DiscordAudioPacket packet) + { + await SendPacket(DiscordAudioPacket.EchoPacket(packet.AsRawPacket(), Params.ssrc)).ConfigureAwait(false); + } + /// + /// Sends a given DiscordAudioPacket over the UDP client.. + /// + /// + /// + public async Task SendPacket(DiscordAudioPacket packet) + { + if (_udp != null && VoiceWebSocket.State == WebSocketState.Open) + { +#if NETFX4_5 + await _udp.SendAsync(packet.AsRawPacket(), packet.AsRawPacket().Length).ConfigureAwait(false); +#else + _udp.Send(packet.AsRawPacket(), packet.AsRawPacket().Length); +#endif + VoiceDebugLogger.Log("Sent packet through SendPacket task.", MessageLevel.Unecessary); + } + } + /// + /// Whether or not the current client is set to be speaking. + /// + /// If true, you will be set to speaking. + public void SetSpeaking(bool speaking) + { + if (VoiceWebSocket != null) + { + if (VoiceWebSocket.State == WebSocketState.Open) + { + string speakingJson = JsonConvert.SerializeObject(new + { + op = 5, + d = new + { + speaking = speaking, + delay = 0 + } + }); + VoiceDebugLogger.Log("Sending voice speaking ( " + speakingJson + " ) ", MessageLevel.Unecessary); + VoiceWebSocket.Send(speakingJson); + } + else + VoiceDebugLogger.Log("VoiceWebSocket not alive?", MessageLevel.Critical); + } + else + VoiceDebugLogger.Log("VoiceWebSocket null?", MessageLevel.Critical); + } +#endregion + +#region Cleanup + bool disposed = false; + SafeHandle handle = new SafeFileHandle(IntPtr.Zero, true); + protected virtual void Dispose(bool disposing) + { + if (disposed) + return; + if(disposing) + { + handle.Dispose(); + + VoiceSendThread.Abort(); + UDPKeepAliveThread.Abort(); + WebsocketKeepAliveThread.Abort(); + + Connected = false; + if (VoiceWebSocket != null) + { + VoiceWebSocket.Closed -= VoiceWebSocket_OnClose; + VoiceWebSocket.Error -= VoiceWebSocket_OnError; + VoiceWebSocket.Close(); + } + VoiceWebSocket = null; + globalTaskSource.Cancel(false); + globalTaskSource.Dispose(); + if (_udp != null) + _udp.Close(); + _udp = null; + } + disposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + + if (Disposed != null) + Disposed(this, new EventArgs()); + } +#endregion + } +} diff --git a/DiscordSharp/Voice/OpusConverter.cs b/.NET core/DiscordSharp/Voice/OpusConverter.cs similarity index 100% rename from DiscordSharp/Voice/OpusConverter.cs rename to .NET core/DiscordSharp/Voice/OpusConverter.cs diff --git a/DiscordSharp/Voice/OpusDecoder.cs b/.NET core/DiscordSharp/Voice/OpusDecoder.cs similarity index 100% rename from DiscordSharp/Voice/OpusDecoder.cs rename to .NET core/DiscordSharp/Voice/OpusDecoder.cs diff --git a/DiscordSharp/Voice/OpusEncoder.cs b/.NET core/DiscordSharp/Voice/OpusEncoder.cs similarity index 100% rename from DiscordSharp/Voice/OpusEncoder.cs rename to .NET core/DiscordSharp/Voice/OpusEncoder.cs diff --git a/DiscordSharp/Voice/Sodium.cs b/.NET core/DiscordSharp/Voice/Sodium.cs similarity index 100% rename from DiscordSharp/Voice/Sodium.cs rename to .NET core/DiscordSharp/Voice/Sodium.cs diff --git a/DiscordSharp/WebWrapper.cs b/.NET core/DiscordSharp/WebWrapper.cs similarity index 100% rename from DiscordSharp/WebWrapper.cs rename to .NET core/DiscordSharp/WebWrapper.cs diff --git a/.DS_Store b/.NET framework/.DS_Store similarity index 100% rename from .DS_Store rename to .NET framework/.DS_Store diff --git a/.travis.yml b/.NET framework/.travis.yml similarity index 100% rename from .travis.yml rename to .NET framework/.travis.yml diff --git a/.NET framework/DiscordSharp.Commands/CommandStub.cs b/.NET framework/DiscordSharp.Commands/CommandStub.cs new file mode 100644 index 0000000..61f37fc --- /dev/null +++ b/.NET framework/DiscordSharp.Commands/CommandStub.cs @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using DiscordSharp.Objects; + +namespace DiscordSharp.Commands +{ + /// + /// A basic command providing arguments as strings. + /// + public class CommandStub : ICommand + { + internal override Type __typeofCommand + { + get + { + return typeof(CommandStub); + } + set + { + base.__typeofCommand = value; + } + } + + internal CommandStub() + { + this.ID = IDGenerator.GenerateRandomCode(); + } + + public CommandStub(string name, string description, string helpTag) + { + this.ID = IDGenerator.GenerateRandomCode(); + + CommandName = name; + Description = description; + HelpTag = helpTag; + + Args = new List(); + } + + public CommandStub(string name, string description) + { + this.ID = IDGenerator.GenerateRandomCode(); + + CommandName = name; + Description = description; + + Args = new List(); + } + + public CommandStub(Action action) + { + this.ID = IDGenerator.GenerateRandomCode(); + + Do = action; + + Args = new List(); + } + + public CommandStub(string name, string description, Action action) + { + this.ID = IDGenerator.GenerateRandomCode(); + + Do = action; + CommandName = name; + Description = description; + + Args = new List(); + } + + public CommandStub(string name, string description, string helpTag, Action action) + { + this.ID = IDGenerator.GenerateRandomCode(); + + Do = action; + CommandName = name; + Description = description; + HelpTag = helpTag; + + Args = new List(); + } + + public CommandStub(string name, string description, string helpTag, PermissionType minPerm, Action action) + { + this.ID = IDGenerator.GenerateRandomCode(); + + Do = action; + CommandName = name; + Description = description; + HelpTag = helpTag; + MinimumPermission = minPerm; + + Args = new List(); + } + + public CommandStub(string name, string description, string helpTag, PermissionType minPerm, int argCount, Action action) + { + this.ID = IDGenerator.GenerateRandomCode(); + + Do = action; + CommandName = name; + Description = description; + HelpTag = helpTag; + MinimumPermission = minPerm; + ArgCount = argCount; + + Args = new List(); + } + + [Obsolete] + public override void ExecuteCommand() + { + CommandArgs e = new CommandArgs(); + e.Args = this.Args; + Do.Invoke(e); + } + + public override void ExecuteCommand(DiscordChannel channel, DiscordMember member) + { + CommandArgs e = new CommandArgs(); + e.Args = this.Args; + e.Author = member; + e.Channel = channel; + + if ((int)CommandsManager.GetPermissionFromID(member.ID) >= (int)MinimumPermission) + Do.Invoke(e); + else + throw new UnauthorizedAccessException($"You have no permission to execute this command! (Minimum needed: {(MinimumPermission.ToString().Substring(MinimumPermission.ToString().IndexOf('.') + 1))})"); + } + } +} diff --git a/.NET framework/DiscordSharp.Commands/CommandsManager.cs b/.NET framework/DiscordSharp.Commands/CommandsManager.cs new file mode 100644 index 0000000..9ad7eeb --- /dev/null +++ b/.NET framework/DiscordSharp.Commands/CommandsManager.cs @@ -0,0 +1,265 @@ +using DiscordSharp.Objects; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DiscordSharp.Commands +{ + public class ModuleNotEnabledException : Exception + { + IModule module; + public IModule Module + { + get { return module; } + } + public ModuleNotEnabledException(string message, IModule module) : base(message) + { + this.module = module; + } + } + + public class BaseModuleToggleException : Exception + { + public BaseModuleToggleException(string message) : base(message) { } + } + + public class CommandsManager + { + private readonly DiscordClient __client; + public DiscordClient Client + { + get + { + return __client; + } + } + + public Random rng = new Random((int)DateTime.Now.Ticks); + + private List __commands; + public List Commands + { + get { return __commands; } + } + + /// + /// Key value pair of the modules. + /// Key = module + /// Value = Whether or not the module is enabled. + /// + private Dictionary __modules; + public Dictionary Modules + { + get { return __modules; } + } + + //id, permission + private static Dictionary __internalUserRoles; + public static Dictionary UserRoles + { + get + { + return __internalUserRoles; + } + } + + internal static PermissionType GetPermissionFromID(string id) + { + if (__internalUserRoles.Count > 0) + { + foreach(var perm in __internalUserRoles) + { + if (perm.Key == id) + return perm.Value; + } + return PermissionType.User; + } + else + return PermissionType.User; + } + + public CommandsManager(DiscordClient client) + { + __client = client; + __commands = new List(); + __modules = new Dictionary(); + __internalUserRoles = new Dictionary(); + Console.Write(""); + } + + public bool HasPermission(DiscordMember member, PermissionType permission) + { + if(__internalUserRoles.ContainsKey(member.ID)) + { + foreach (var perm in __internalUserRoles) + if (perm.Key == member.ID && (int)perm.Value >= (int)permission) + return true; + } + return false; + } + + public void AddPermission(DiscordMember member, PermissionType permission) + { + if (__internalUserRoles.ContainsKey(member.ID)) + __internalUserRoles.Remove(member.ID); + __internalUserRoles.Add(member.ID, permission); + } + public void AddPermission(string memberID, PermissionType permission) + { + if (__internalUserRoles.ContainsKey(memberID)) + __internalUserRoles.Remove(memberID); + __internalUserRoles.Add(memberID, permission); + } + + public void OverridePermissionsDictionary(Dictionary dict) => __internalUserRoles = dict; + + public void OverrideModulesDictionary(Dictionary dictionary) + { + foreach (IModule kvp in __modules.Keys.ToList()) + { + if (kvp.Name.ToLower().Trim() != "base") + { + if (dictionary.ContainsKey(kvp.Name.ToLower().Trim())) + __modules[kvp] = dictionary[kvp.Name.ToLower().Trim()]; + } + } + } + + public Dictionary ModuleDictionaryForJson() + { + Dictionary dict = new Dictionary(); + + lock(__modules) + { + foreach (var kvp in __modules) + { + if (kvp.Key.Name.ToLower().Trim() != "base") + dict.Add(kvp.Key.Name, kvp.Value); + } + } + + return dict; + } + + public int ExecuteOnMessageCommand(string rawCommandText, DiscordChannel channel, DiscordMember author) + { + string[] split = rawCommandText.Split(new char[] { ' ' }); //splits into args and stuff + try + { + var command = __commands.Find(x => x.CommandName == split[0]); + + if (command != null && command.Parent != null) //if it's a generic command without a parent then don't bother doing this. + { + lock(__modules) + { + if (__modules[command.Parent] == false) + { + throw new ModuleNotEnabledException($"The specified module {command.Parent.Name} is not enabled.", command.Parent); + } + } + } + + if(command != null) + { + command.Args.Clear(); + if (command.ArgCount > 0) + { + string[] argsSplit = rawCommandText.Split(new char[] { ' ' }, command.ArgCount + 1); + //adds all the arguments + for (int i = 1; i < argsSplit.Length; i++) + command.AddArgument(argsSplit[i]); + } + //finally, executes it + command.ExecuteCommand(channel, author); + return 0; + } + } + catch(UnauthorizedAccessException uaex) + { + throw uaex; //no permission + } + catch(Exception ex) + { + throw ex; + } + return 1; + } + + public bool ModuleEnabled(string name) + { + lock(__modules) + { + foreach (var kvp in __modules) + { + if (kvp.Key.Name.ToLower().Trim() == name.ToLower().Trim()) + { + return __modules[kvp.Key]; + } + } + } + return false; + } + + public void EnableModule(string name) + { + lock(__modules) + { + foreach (var kvp in __modules) + { + if (kvp.Key.Name.ToLower().Trim() == name.ToLower().Trim()) //if module exists + { + __modules[kvp.Key] = true; //enabled + break; + } + } + } + } + + public void DisableModule(string name) + { + if (name.ToLower().Trim() == "base") + throw new BaseModuleToggleException("Can't disable base module!"); + + lock(__modules) + { + foreach (var kvp in __modules) + { + if (kvp.Key.Name.ToLower().Trim() == name.ToLower().Trim()) //if module exists + { + __modules[kvp.Key] = false; //disable it + break; + } + } + } + } + + /// + /// Adds a generic command without an associated module. + /// + /// + public void AddCommand(ICommand command) => __commands.Add(command); + + /// + /// Adds a command with an assosciated module. + /// + /// + /// + public void AddCommand(ICommand command, IModule fromModule) + { + command.Parent = fromModule; + command.Parent.Commands.Add(command); + lock(__modules) + { + if (!__modules.ContainsKey(fromModule)) + __modules.Add(fromModule, true); + + if (__modules[fromModule] == false) //if you're adding the command, you're enabling the module. + __modules[fromModule] = true; + } + + __commands.Add(command); + } + } +} diff --git a/DiscordSharp.Commands/DiscordSharp.Commands.csproj b/.NET framework/DiscordSharp.Commands/DiscordSharp.Commands.csproj similarity index 92% rename from DiscordSharp.Commands/DiscordSharp.Commands.csproj rename to .NET framework/DiscordSharp.Commands/DiscordSharp.Commands.csproj index a07a430..fc913bf 100644 --- a/DiscordSharp.Commands/DiscordSharp.Commands.csproj +++ b/.NET framework/DiscordSharp.Commands/DiscordSharp.Commands.csproj @@ -1,5 +1,5 @@  - + Debug @@ -9,8 +9,9 @@ Properties DiscordSharp.Commands DiscordSharp.Commands - v4.5 + v4.6.1 512 + true diff --git a/.NET framework/DiscordSharp.Commands/ICommand.cs b/.NET framework/DiscordSharp.Commands/ICommand.cs new file mode 100644 index 0000000..23bfeb0 --- /dev/null +++ b/.NET framework/DiscordSharp.Commands/ICommand.cs @@ -0,0 +1,70 @@ +using DiscordSharp.Objects; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DiscordSharp.Commands +{ + public class CommandArgs + { + public List Args { get; internal set; } + public DiscordChannel Channel { get; internal set; } + public DiscordMember Author { get; internal set; } + } + + public abstract class ICommand + { + /// + /// The trigger of the command you want to run. + /// Example: help, random, die, 8ball + /// + public virtual string CommandName { get; set; } + + /// + /// A short description of the command. + /// + public virtual string Description { get; set; } + + /// + /// A help tag for using the command + /// + public virtual string HelpTag { get; set; } + + /// + /// The arguments this command can take. + /// + public virtual List Args { get; set; } + + public virtual int ArgCount { get; set; } + + /// + /// The module this command came from. + /// + public virtual IModule Parent { get; internal set; } + + /// + /// The permission type that the command takes. + /// + public virtual PermissionType MinimumPermission { get; set; } = PermissionType.User; + + public virtual Action Do { get; internal set; } + + internal virtual Type __typeofCommand { get; set; } + public virtual string ID { get; set; } + + public abstract void ExecuteCommand(); + public abstract void ExecuteCommand(DiscordChannel channel, DiscordMember member); + + //public string ReturnArgument(string argName) + //{ + // return Args.Select(m => m).Where(x => x.Key == argName).Select(k => k.Value).First(); + //} + + public void AddArgument(string argValue) + { + Args.Add(argValue); + } + } +} diff --git a/.NET framework/DiscordSharp.Commands/IDGenerator.cs b/.NET framework/DiscordSharp.Commands/IDGenerator.cs new file mode 100644 index 0000000..094bbde --- /dev/null +++ b/.NET framework/DiscordSharp.Commands/IDGenerator.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace DiscordSharp.Commands +{ + public class IDGenerator + { + private static Random AlphaGenerator = new Random(DateTime.Now.Millisecond); + private static Random NumericalGenerator = new Random((int)(DateTime.Now.Millisecond * 98734)); + + private static String[] Alphabet = new string[] { "a", "b", "c", "d", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" }; + + internal IDGenerator() { } + + public static string GenerateRandomCode() + { + List code = new List(); + for (int i = 0; i < 25; i++) + { + int letterOrNum = NumericalGenerator.Next(0, 9); + if (IsOdd(letterOrNum)) //alpha + { + string letter = Alphabet[AlphaGenerator.Next(0, Alphabet.Length - 1)]; + if (code.Count > 0) + while (letter == code[i - 1]) + letter = Alphabet[AlphaGenerator.Next(0, Alphabet.Length - 1)]; + code.Add(letter); + } + else //num + { + int num = NumericalGenerator.Next(0, 9); + if (code.Count > 0) + while (num.ToString() == code[i - 1]) + num = NumericalGenerator.Next(0, 9); + code.Add(num.ToString()); + } + } + + + return ArrayToString(code.ToArray()); + } + + private static string ArrayToString(String[] array) + { + string code = ""; + for (int i = 0; i < array.Length - 1; i++) + { + code += array[i]; + } + return code; + } + + private static bool IsOdd(int num) + { + return num % 2 != 0; + } + } +} \ No newline at end of file diff --git a/.NET framework/DiscordSharp.Commands/IModule.cs b/.NET framework/DiscordSharp.Commands/IModule.cs new file mode 100644 index 0000000..8d3b2c6 --- /dev/null +++ b/.NET framework/DiscordSharp.Commands/IModule.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DiscordSharp.Commands +{ + public abstract class IModule + { + /// + /// The name of the module. + /// + public virtual string Name { get; set; } = "module"; + + /// + /// A description talking about what the module contains + /// + public virtual string Description { get; set; } = "Please set this in the constructor of your IModule derivative."; + + /// + /// A list of the commands this module contains + /// + public virtual List Commands { get; internal set; } = new List(); + + /// + /// Installs the module's commands into the commands manager + /// + /// + public abstract void Install(CommandsManager manager); + + /// + /// Uninstall's this modules's commands from the given module manager. + /// + /// + public void Uninstall(CommandsManager manager) + { + lock (manager.Commands) + { + foreach (var command in manager.Commands) + { + var thisModulesCommand = Commands.Find(x => x.ID == command.ID && x.Parent.Name == this.Name); //compare modules by name just in case + if (thisModulesCommand != null) + manager.Commands.Remove(command); + } + } + } + + } +} diff --git a/.NET framework/DiscordSharp.Commands/Permission.cs b/.NET framework/DiscordSharp.Commands/Permission.cs new file mode 100644 index 0000000..098b028 --- /dev/null +++ b/.NET framework/DiscordSharp.Commands/Permission.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DiscordSharp.Commands +{ + public enum PermissionType : int + { + Owner = 666, + Admin = 2, + Mod = 1, + User = 0, + None = -666 + } +} diff --git a/DiscordSharp.Commands/Properties/AssemblyInfo.cs b/.NET framework/DiscordSharp.Commands/Properties/AssemblyInfo.cs similarity index 100% rename from DiscordSharp.Commands/Properties/AssemblyInfo.cs rename to .NET framework/DiscordSharp.Commands/Properties/AssemblyInfo.cs diff --git a/DiscordSharp.sln b/.NET framework/DiscordSharp.sln similarity index 98% rename from DiscordSharp.sln rename to .NET framework/DiscordSharp.sln index c396374..dda7796 100644 --- a/DiscordSharp.sln +++ b/.NET framework/DiscordSharp.sln @@ -1,104 +1,104 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordSharp", "DiscordSharp\DiscordSharp.csproj", "{A96FFE9E-3650-4976-872E-5BB336CC1589}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Luigibot", "DiscordSharpTestApplication\Luigibot.csproj", "{02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordSharp.Commands", "DiscordSharp.Commands\DiscordSharp.Commands.csproj", "{2E99D97F-3480-43E2-AC9D-7DAE521CB610}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - DebugDLL|Any CPU = DebugDLL|Any CPU - DebugDLL|x64 = DebugDLL|x64 - DebugDLL|x86 = DebugDLL|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - ReleaseDLL|Any CPU = ReleaseDLL|Any CPU - ReleaseDLL|x64 = ReleaseDLL|x64 - ReleaseDLL|x86 = ReleaseDLL|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|x64.ActiveCfg = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|x64.Build.0 = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|x86.ActiveCfg = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|x86.Build.0 = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|Any CPU.ActiveCfg = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|Any CPU.Build.0 = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|x64.ActiveCfg = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|x64.Build.0 = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|x86.ActiveCfg = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|x86.Build.0 = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|Any CPU.Build.0 = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|x64.ActiveCfg = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|x64.Build.0 = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|x86.ActiveCfg = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|x86.Build.0 = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|Any CPU.ActiveCfg = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|Any CPU.Build.0 = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|x64.ActiveCfg = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|x64.Build.0 = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|x86.ActiveCfg = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|x86.Build.0 = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|x64.ActiveCfg = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|x64.Build.0 = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|x86.ActiveCfg = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|x86.Build.0 = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|Any CPU.ActiveCfg = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|Any CPU.Build.0 = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|x64.ActiveCfg = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|x64.Build.0 = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|x86.ActiveCfg = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|x86.Build.0 = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|Any CPU.Build.0 = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|x64.ActiveCfg = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|x64.Build.0 = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|x86.ActiveCfg = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|x86.Build.0 = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|Any CPU.ActiveCfg = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|Any CPU.Build.0 = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|x64.ActiveCfg = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|x64.Build.0 = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|x86.ActiveCfg = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|x86.Build.0 = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|x64.ActiveCfg = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|x64.Build.0 = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|x86.ActiveCfg = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|x86.Build.0 = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|Any CPU.ActiveCfg = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|Any CPU.Build.0 = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|x64.ActiveCfg = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|x64.Build.0 = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|x86.ActiveCfg = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|x86.Build.0 = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|Any CPU.Build.0 = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|x64.ActiveCfg = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|x64.Build.0 = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|x86.ActiveCfg = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|x86.Build.0 = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|Any CPU.ActiveCfg = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|Any CPU.Build.0 = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|x64.ActiveCfg = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|x64.Build.0 = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|x86.ActiveCfg = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|x86.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25123.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordSharp", "DiscordSharp\DiscordSharp.csproj", "{A96FFE9E-3650-4976-872E-5BB336CC1589}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Luigibot", "DiscordSharpTestApplication\Luigibot.csproj", "{02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordSharp.Commands", "DiscordSharp.Commands\DiscordSharp.Commands.csproj", "{2E99D97F-3480-43E2-AC9D-7DAE521CB610}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + DebugDLL|Any CPU = DebugDLL|Any CPU + DebugDLL|x64 = DebugDLL|x64 + DebugDLL|x86 = DebugDLL|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + ReleaseDLL|Any CPU = ReleaseDLL|Any CPU + ReleaseDLL|x64 = ReleaseDLL|x64 + ReleaseDLL|x86 = ReleaseDLL|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|x64.ActiveCfg = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|x64.Build.0 = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|x86.ActiveCfg = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|x86.Build.0 = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|Any CPU.ActiveCfg = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|Any CPU.Build.0 = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|x64.ActiveCfg = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|x64.Build.0 = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|x86.ActiveCfg = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|x86.Build.0 = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|Any CPU.Build.0 = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|x64.ActiveCfg = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|x64.Build.0 = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|x86.ActiveCfg = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|x86.Build.0 = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|Any CPU.ActiveCfg = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|Any CPU.Build.0 = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|x64.ActiveCfg = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|x64.Build.0 = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|x86.ActiveCfg = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|x86.Build.0 = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|x64.ActiveCfg = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|x64.Build.0 = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|x86.ActiveCfg = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|x86.Build.0 = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|Any CPU.ActiveCfg = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|Any CPU.Build.0 = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|x64.ActiveCfg = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|x64.Build.0 = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|x86.ActiveCfg = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|x86.Build.0 = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|Any CPU.Build.0 = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|x64.ActiveCfg = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|x64.Build.0 = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|x86.ActiveCfg = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|x86.Build.0 = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|Any CPU.ActiveCfg = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|Any CPU.Build.0 = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|x64.ActiveCfg = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|x64.Build.0 = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|x86.ActiveCfg = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|x86.Build.0 = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|x64.ActiveCfg = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|x64.Build.0 = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|x86.ActiveCfg = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|x86.Build.0 = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|Any CPU.ActiveCfg = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|Any CPU.Build.0 = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|x64.ActiveCfg = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|x64.Build.0 = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|x86.ActiveCfg = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|x86.Build.0 = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|Any CPU.Build.0 = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|x64.ActiveCfg = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|x64.Build.0 = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|x86.ActiveCfg = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|x86.Build.0 = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|Any CPU.ActiveCfg = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|Any CPU.Build.0 = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|x64.ActiveCfg = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|x64.Build.0 = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|x86.ActiveCfg = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DiscordSharp.sln.save b/.NET framework/DiscordSharp.sln.save similarity index 98% rename from DiscordSharp.sln.save rename to .NET framework/DiscordSharp.sln.save index 4bf573c..e719fbc 100644 --- a/DiscordSharp.sln.save +++ b/.NET framework/DiscordSharp.sln.save @@ -1,150 +1,150 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.24720.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordSharp", "DiscordSharp\DiscordSharp.csproj", "{A96FFE9E-3650-4976-872E-5BB336CC1589}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Luigibot", "DiscordSharpTestApplication\Luigibot.csproj", "{02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommandsTest", "VoiceCaptureTest\CommandsTest.csproj", "{8CD30B38-9D45-4E49-94F9-7A48977CDA49}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordSharp.Commands", "DiscordSharp.Commands\DiscordSharp.Commands.csproj", "{2E99D97F-3480-43E2-AC9D-7DAE521CB610}" -EndProject -bal - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - DebugDLL|Any CPU = DebugDLL|Any CPU - DebugDLL|x64 = DebugDLL|x64 - DebugDLL|x86 = DebugDLL|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - ReleaseDLL|Any CPU = ReleaseDLL|Any CPU - ReleaseDLL|x64 = ReleaseDLL|x64 - ReleaseDLL|x86 = ReleaseDLL|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|x64.ActiveCfg = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|x64.Build.0 = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|x86.ActiveCfg = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|x86.Build.0 = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|Any CPU.ActiveCfg = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|Any CPU.Build.0 = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|x64.ActiveCfg = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|x64.Build.0 = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|x86.ActiveCfg = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|x86.Build.0 = Debug|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|Any CPU.Build.0 = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|x64.ActiveCfg = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|x64.Build.0 = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|x86.ActiveCfg = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|x86.Build.0 = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|Any CPU.ActiveCfg = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|Any CPU.Build.0 = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|x64.ActiveCfg = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|x64.Build.0 = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|x86.ActiveCfg = Release|Any CPU - {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|x86.Build.0 = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|x64.ActiveCfg = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|x64.Build.0 = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|x86.ActiveCfg = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|x86.Build.0 = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|Any CPU.ActiveCfg = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|Any CPU.Build.0 = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|x64.ActiveCfg = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|x64.Build.0 = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|x86.ActiveCfg = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|x86.Build.0 = Debug|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|Any CPU.Build.0 = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|x64.ActiveCfg = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|x64.Build.0 = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|x86.ActiveCfg = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|x86.Build.0 = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|Any CPU.ActiveCfg = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|Any CPU.Build.0 = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|x64.ActiveCfg = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|x64.Build.0 = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|x86.ActiveCfg = Release|Any CPU - {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|x86.Build.0 = Release|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Debug|x64.ActiveCfg = Debug|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Debug|x64.Build.0 = Debug|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Debug|x86.ActiveCfg = Debug|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Debug|x86.Build.0 = Debug|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.DebugDLL|Any CPU.ActiveCfg = Debug|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.DebugDLL|Any CPU.Build.0 = Debug|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.DebugDLL|x64.ActiveCfg = Debug|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.DebugDLL|x64.Build.0 = Debug|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.DebugDLL|x86.ActiveCfg = Debug|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.DebugDLL|x86.Build.0 = Debug|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Release|Any CPU.Build.0 = Release|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Release|x64.ActiveCfg = Release|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Release|x64.Build.0 = Release|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Release|x86.ActiveCfg = Release|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Release|x86.Build.0 = Release|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.ReleaseDLL|Any CPU.ActiveCfg = Release|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.ReleaseDLL|Any CPU.Build.0 = Release|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.ReleaseDLL|x64.ActiveCfg = Release|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.ReleaseDLL|x64.Build.0 = Release|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.ReleaseDLL|x86.ActiveCfg = Release|Any CPU - {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.ReleaseDLL|x86.Build.0 = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|x64.ActiveCfg = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|x64.Build.0 = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|x86.ActiveCfg = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|x86.Build.0 = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|Any CPU.ActiveCfg = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|Any CPU.Build.0 = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|x64.ActiveCfg = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|x64.Build.0 = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|x86.ActiveCfg = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|x86.Build.0 = Debug|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|Any CPU.Build.0 = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|x64.ActiveCfg = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|x64.Build.0 = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|x86.ActiveCfg = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|x86.Build.0 = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|Any CPU.ActiveCfg = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|Any CPU.Build.0 = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|x64.ActiveCfg = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|x64.Build.0 = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|x86.ActiveCfg = Release|Any CPU - {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|x86.Build.0 = Release|Any CPU - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|x64.ActiveCfg = Debug|x64 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|x64.Build.0 = Debug|x64 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|x86.ActiveCfg = Debug|Win32 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|x86.Build.0 = Debug|Win32 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DebugDLL|Any CPU.ActiveCfg = DebugDLL|Win32 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DebugDLL|x64.Build.0 = DebugDLL|x64 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DebugDLL|x86.Build.0 = DebugDLL|Win32 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|Any CPU.ActiveCfg = Release|Win32 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|x64.ActiveCfg = Release|x64 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|x64.Build.0 = Release|x64 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|x86.ActiveCfg = Release|Win32 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|x86.Build.0 = Release|Win32 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.ReleaseDLL|Any CPU.ActiveCfg = ReleaseDLL|Win32 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32 - {A185B162-6CB6-4502-B03F-B56F7699A8D9}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.24720.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordSharp", "DiscordSharp\DiscordSharp.csproj", "{A96FFE9E-3650-4976-872E-5BB336CC1589}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Luigibot", "DiscordSharpTestApplication\Luigibot.csproj", "{02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommandsTest", "VoiceCaptureTest\CommandsTest.csproj", "{8CD30B38-9D45-4E49-94F9-7A48977CDA49}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordSharp.Commands", "DiscordSharp.Commands\DiscordSharp.Commands.csproj", "{2E99D97F-3480-43E2-AC9D-7DAE521CB610}" +EndProject +bal + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + DebugDLL|Any CPU = DebugDLL|Any CPU + DebugDLL|x64 = DebugDLL|x64 + DebugDLL|x86 = DebugDLL|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + ReleaseDLL|Any CPU = ReleaseDLL|Any CPU + ReleaseDLL|x64 = ReleaseDLL|x64 + ReleaseDLL|x86 = ReleaseDLL|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|x64.ActiveCfg = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|x64.Build.0 = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|x86.ActiveCfg = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Debug|x86.Build.0 = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|Any CPU.ActiveCfg = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|Any CPU.Build.0 = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|x64.ActiveCfg = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|x64.Build.0 = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|x86.ActiveCfg = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.DebugDLL|x86.Build.0 = Debug|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|Any CPU.Build.0 = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|x64.ActiveCfg = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|x64.Build.0 = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|x86.ActiveCfg = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.Release|x86.Build.0 = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|Any CPU.ActiveCfg = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|Any CPU.Build.0 = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|x64.ActiveCfg = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|x64.Build.0 = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|x86.ActiveCfg = Release|Any CPU + {A96FFE9E-3650-4976-872E-5BB336CC1589}.ReleaseDLL|x86.Build.0 = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|x64.ActiveCfg = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|x64.Build.0 = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|x86.ActiveCfg = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Debug|x86.Build.0 = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|Any CPU.ActiveCfg = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|Any CPU.Build.0 = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|x64.ActiveCfg = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|x64.Build.0 = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|x86.ActiveCfg = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.DebugDLL|x86.Build.0 = Debug|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|Any CPU.Build.0 = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|x64.ActiveCfg = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|x64.Build.0 = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|x86.ActiveCfg = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.Release|x86.Build.0 = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|Any CPU.ActiveCfg = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|Any CPU.Build.0 = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|x64.ActiveCfg = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|x64.Build.0 = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|x86.ActiveCfg = Release|Any CPU + {02AA3864-7A3D-45E4-92DE-C6DAE8972ABF}.ReleaseDLL|x86.Build.0 = Release|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Debug|x64.ActiveCfg = Debug|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Debug|x64.Build.0 = Debug|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Debug|x86.ActiveCfg = Debug|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Debug|x86.Build.0 = Debug|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.DebugDLL|Any CPU.ActiveCfg = Debug|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.DebugDLL|Any CPU.Build.0 = Debug|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.DebugDLL|x64.ActiveCfg = Debug|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.DebugDLL|x64.Build.0 = Debug|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.DebugDLL|x86.ActiveCfg = Debug|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.DebugDLL|x86.Build.0 = Debug|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Release|Any CPU.Build.0 = Release|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Release|x64.ActiveCfg = Release|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Release|x64.Build.0 = Release|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Release|x86.ActiveCfg = Release|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.Release|x86.Build.0 = Release|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.ReleaseDLL|Any CPU.ActiveCfg = Release|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.ReleaseDLL|Any CPU.Build.0 = Release|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.ReleaseDLL|x64.ActiveCfg = Release|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.ReleaseDLL|x64.Build.0 = Release|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.ReleaseDLL|x86.ActiveCfg = Release|Any CPU + {8CD30B38-9D45-4E49-94F9-7A48977CDA49}.ReleaseDLL|x86.Build.0 = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|x64.ActiveCfg = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|x64.Build.0 = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|x86.ActiveCfg = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Debug|x86.Build.0 = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|Any CPU.ActiveCfg = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|Any CPU.Build.0 = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|x64.ActiveCfg = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|x64.Build.0 = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|x86.ActiveCfg = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.DebugDLL|x86.Build.0 = Debug|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|Any CPU.Build.0 = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|x64.ActiveCfg = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|x64.Build.0 = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|x86.ActiveCfg = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.Release|x86.Build.0 = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|Any CPU.ActiveCfg = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|Any CPU.Build.0 = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|x64.ActiveCfg = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|x64.Build.0 = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|x86.ActiveCfg = Release|Any CPU + {2E99D97F-3480-43E2-AC9D-7DAE521CB610}.ReleaseDLL|x86.Build.0 = Release|Any CPU + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|x64.ActiveCfg = Debug|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|x64.Build.0 = Debug|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|x86.ActiveCfg = Debug|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|x86.Build.0 = Debug|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DebugDLL|Any CPU.ActiveCfg = DebugDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DebugDLL|x86.ActiveCfg = DebugDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DebugDLL|x86.Build.0 = DebugDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|Any CPU.ActiveCfg = Release|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|x64.ActiveCfg = Release|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|x64.Build.0 = Release|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|x86.ActiveCfg = Release|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|x86.Build.0 = Release|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.ReleaseDLL|Any CPU.ActiveCfg = ReleaseDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.ReleaseDLL|x86.ActiveCfg = ReleaseDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.ReleaseDLL|x86.Build.0 = ReleaseDLL|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/.NET framework/DiscordSharp/Color.cs b/.NET framework/DiscordSharp/Color.cs new file mode 100644 index 0000000..f087699 --- /dev/null +++ b/.NET framework/DiscordSharp/Color.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DiscordSharp +{ + /// + /// Custom color class just because. + /// + public class Color + { + public uint R { get; set; } + public uint G { get; set; } + public uint B { get; set; } + + private uint raw; + + public Color(string hex) + { + uint asActualHex = Convert.ToUInt32(hex, 16); + + //01 23 45 67 + //FF FF FF FF + R = (uint)(asActualHex >> 16) & 0xFF; + G = (uint)(asActualHex >> 8) & 0xFF; + B = (uint)(asActualHex & 0xFF); + //A = (asActualHex >> 24) & 0xFF + raw = asActualHex; + } + + public int ToDecimal() + { + return (int)raw; + } + + public override string ToString() + { + return string.Format("{0:X}", raw); + } + } +} diff --git a/.NET framework/DiscordSharp/DiscordClient.cs b/.NET framework/DiscordSharp/DiscordClient.cs new file mode 100644 index 0000000..9f44d4c --- /dev/null +++ b/.NET framework/DiscordSharp/DiscordClient.cs @@ -0,0 +1,3414 @@ +using System; +using System.Threading.Tasks; +using Newtonsoft.Json; +using System.Net; +using System.IO; +using System.Threading; +using System.Collections.Generic; +using Newtonsoft.Json.Linq; +using DiscordSharp.Events; +using System.Drawing; +using System.Linq; +using DiscordSharp.Objects; +using DiscordSharp.Sockets; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using DiscordSharp.Sockets.BuiltIn; + +namespace DiscordSharp +{ + /// + /// Properties that Discord uses upon connection to the websocket. Mostly used for analytics internally. + /// + public class DiscordProperties + { + /// + /// The OS you're on + /// + [JsonProperty("$os")] + public string OS { get; set; } + + /// + /// The "browser" you're using. + /// + [JsonProperty("$browser")] + public string Browser { get; set; } + + /// + /// Whatever device you want to be on. (Default: DiscordSharp Bot) + /// + [JsonProperty("$device")] + public string Device + { get; set; } = "DiscordSharp Bot"; + + /// + /// + /// + [JsonProperty("$referrer")] + public string referrer { get; set; } + /// + /// + /// + [JsonProperty("$referring_domain")] + public string referring_domain { get; set; } + + /// + /// Default constructor setting the OS property to Environment.OSVersion.ToString(); + /// + public DiscordProperties() + { + OS = Environment.OSVersion.ToString(); + } + + /// + /// Serializes this object as json. + /// + /// Json string of this object serialized + public string AsJson() + { + return JsonConvert.SerializeObject(this); + } + } + + /// + /// The type of message that the Discord message is. + /// + public enum DiscordMessageType + { + /// + /// Private/DM + /// + PRIVATE, + /// + /// Public/in a channel. + /// + CHANNEL + } + + /// + /// Where the magic happens. + /// + public class DiscordClient + { + /// + /// The token associated with authenticating your bot and ensuring they can send messages. + /// + public static string token { get; internal set; } = null; + /// + /// If this is true, the account this client is running on is a special bot account. + /// + public static bool IsBotAccount { get; internal set; } = false; + + /// + /// The URL that the client websocket is currently connected to. + /// + public string CurrentGatewayURL { get; internal set; } + + /// + /// Any private information assosciated with the account (regular clients only) + /// + public DiscordUserInformation ClientPrivateInformation { get; set; } + + /// + /// Custom properties containing parameters such as + /// * OS + /// * Referrer + /// * Browser + /// Used by Discord internally for connection. + /// + public DiscordProperties DiscordProperties { get; set; } = new DiscordProperties(); + + /// + /// Custom properties for the default discord channel to listen to + /// This updates with various events such as offline/online status + /// + public string[] DiscordSyncedGuilds { get; set; } = new string[] { }; + + /// + /// The current DiscordMember object assosciated with the account you're connected to. + /// + public DiscordMember Me { get; internal set; } + + /// + /// Returns the debug logger used to log various debug events. + /// + public Logger GetTextClientLogger => DebugLogger; + + /// + /// Returns the last debug logger for when the voice client was last connected. + /// + public Logger GetLastVoiceClientLogger; + + /// + /// If true, the logger will log everything. + /// Everything. + /// + public bool EnableVerboseLogging { get; set; } = false; + + /// + /// The version of the gateway. + /// + public int DiscordGatewayVersion { get; set; } = 0; + + [Obsolete] + internal bool V4Testing { get; set; } = false; + + /// + /// V4 related things. Getting this means our session has been successfully initiated. + /// + private string SessionID; + + /// + /// The last sequence we received used for v4 heartbeat. + /// + private int Sequence = 0; + + /// + /// Whether or not to send Opcode 6 (resume) upon a socket being closed. + /// + public bool Autoconnect { get; set; } = true; + + + private NetWebSocketWrapper ws; + private List ServersList { get; set; } + private string CurrentGameName = ""; + private int? IdleSinceUnixTime = null; + private DiscordVoiceClient VoiceClient; + private Logger DebugLogger = new Logger(); + private CancellationTokenSource KeepAliveTaskTokenSource = new CancellationTokenSource(); + private CancellationToken KeepAliveTaskToken; + private Task KeepAliveTask; + private Thread VoiceThread; //yuck + private static string StrippedEmail = ""; + + /// + /// Testing. + /// + private List RemovedMembers = new List(); + + /// + /// Whether or not to write the latest READY upon receiving it. + /// If this is true, the client will write the contents of the READY message to 'READY_LATEST.txt' + /// If your client is connected to a lot of servers, this file will be quite large. + /// + public bool WriteLatestReady { get; set; } = false; + + /// + /// Whether or not to request all users in a guild (including offlines) on startup. + /// + public bool RequestAllUsersOnStartup { get; set; } = false; + + /// + /// A log of messages kept in a KeyValuePair. + /// The key is the id of the message, and the value is a DiscordMessage object. If you need raw json, this is contained inside of the DiscordMessage object now. + /// + private Dictionary MessageLog = new Dictionary(); + //private List> MessageLog = new List>(); + private List PrivateChannels = new List(); + + #region Event declaration + public event EventHandler MessageReceived; + public event EventHandler Connected; + public event EventHandler SocketOpened; + public event EventHandler SocketClosed; + public event EventHandler ChannelCreated; + public event EventHandler PrivateChannelCreated; + public event EventHandler PrivateMessageReceived; + public event EventHandler KeepAliveSent; + public event EventHandler MentionReceived; + public event EventHandler UserTypingStart; + public event EventHandler MessageEdited; + public event EventHandler PresenceUpdated; + public event EventHandler URLMessageAutoUpdate; + public event EventHandler VoiceStateUpdate; + public event EventHandler UnknownMessageTypeReceived; + public event EventHandler MessageDeleted; + public event EventHandler UserUpdate; + public event EventHandler UserAddedToServer; + public event EventHandler UserRemovedFromServer; + public event EventHandler GuildCreated; + /// + /// Occurs when a guild becomes available after being unavailable. + /// + public event EventHandler GuildAvailable; + public event EventHandler GuildDeleted; + public event EventHandler ChannelUpdated; + public event EventHandler TextClientDebugMessageReceived; + public event EventHandler VoiceClientDebugMessageReceived; + public event EventHandler ChannelDeleted; + public event EventHandler GuildUpdated; + public event EventHandler RoleDeleted; + public event EventHandler RoleUpdated; + public event EventHandler GuildMemberUpdated; + public event EventHandler GuildMemberBanned; + public event EventHandler GuildMembersLoadedEventArgs; + public event EventHandler PrivateChannelDeleted; + public event EventHandler BanRemoved; + public event EventHandler PrivateMessageDeleted; + + #region Voice + /// + /// For use when connected to voice only. + /// + public event EventHandler AudioPacketReceived; + /// + /// For use when connected to voice only. + /// + public event EventHandler UserSpeaking; + /// + /// For use when connected to voice only. + /// + public event EventHandler UserLeftVoiceChannel; + /// + /// Occurs when the voice client is fully connected to voice. + /// + public event EventHandler VoiceClientConnected; + /// + /// Occurs when the voice queue is emptied. + /// + public event EventHandler VoiceQueueEmpty; + #endregion + #endregion + + /// + /// + /// + /// If you have a token you wish to use, provide it here. Else, a login attempt will be made. + /// Set this to true if your bot is going to be a bot account + public DiscordClient(string tokenOverride = null, bool isBotAccount = false, bool enableLogging = true) + { + if (isBotAccount && tokenOverride == null) + throw new Exception("Token override cannot be null if using a bot account!"); + DebugLogger.EnableLogging = enableLogging; + + token = tokenOverride; + IsBotAccount = isBotAccount; + + if (ClientPrivateInformation == null) + ClientPrivateInformation = new DiscordUserInformation(); + + DebugLogger.LogMessageReceived += (sender, e) => + { + if (e.message.Level == MessageLevel.Error) + DisconnectFromVoice(); + TextClientDebugMessageReceived?.Invoke(this, e); + }; + } + + /// + /// Current DiscordServers you're connected to. + /// + /// DiscordServer list of servers you're currently connected to. + public List GetServersList() => ServersList; + + /// + /// Any messages logged since connection to the websocket. + /// + /// A KeyValuePair list of string-DiscordMessage. Where string is the message's ID + public Dictionary GetMessageLog() => MessageLog; + + /// + /// Private channels assosciated with the account. + /// + /// a list of DiscordPrivateChannels. + public List GetPrivateChannels() => PrivateChannels; + + /// + /// + /// + /// True if connected to voice. + public bool ConnectedToVoice() => VoiceClient != null ? VoiceClient.Connected : false; + + //eh + private void GetChannelsList(JObject m) + { + if (ServersList == null) + ServersList = new List(); + foreach (var j in m["d"]["guilds"]) + { + if (!j["unavailable"].IsNullOrEmpty() && j["unavailable"].ToObject() == true) + continue; //unavailable server + DiscordServer temp = new DiscordServer(); + temp.parentclient = this; + temp.JoinedAt = j["joined_at"].ToObject(); + temp.ID = j["id"].ToString(); + temp.Name = j["name"].ToString(); + if (!j["icon"].IsNullOrEmpty()) + temp.icon = j["icon"].ToString(); + else + temp.icon = null; + + //temp.owner_id = j["owner_id"].ToString(); + List tempSubs = new List(); + + List tempRoles = new List(); + foreach (var u in j["roles"]) + { + DiscordRole t = new DiscordRole + { + Color = new DiscordSharp.Color(u["color"].ToObject().ToString("x")), + Name = u["name"].ToString(), + Permissions = new DiscordPermission(u["permissions"].ToObject()), + Position = u["position"].ToObject(), + Managed = u["managed"].ToObject(), + ID = u["id"].ToString(), + Hoist = u["hoist"].ToObject() + }; + tempRoles.Add(t); + } + temp.Roles = tempRoles; + foreach (var u in j["channels"]) + { + DiscordChannel tempSub = new DiscordChannel(); + tempSub.Client = this; + tempSub.ID = u["id"].ToString(); + tempSub.Name = u["name"].ToString(); + tempSub.Type = u["type"].ToObject(); + if (!u["topic"].IsNullOrEmpty()) + tempSub.Topic = u["topic"].ToString(); + if (tempSub.Type == ChannelType.Voice && !u["bitrate"].IsNullOrEmpty()) + tempSub.Bitrate = u["bitrate"].ToObject(); + tempSub.Parent = temp; + List permissionoverrides = new List(); + foreach (var o in u["permission_overwrites"]) + { + DiscordPermissionOverride dpo = new DiscordPermissionOverride(o["allow"].ToObject(), o["deny"].ToObject()); + dpo.id = o["id"].ToString(); + + if (o["type"].ToString() == "member") + dpo.type = DiscordPermissionOverride.OverrideType.member; + else + dpo.type = DiscordPermissionOverride.OverrideType.role; + + permissionoverrides.Add(dpo); + } + tempSub.PermissionOverrides = permissionoverrides; + + tempSubs.Add(tempSub); + } + temp.Channels = tempSubs; + foreach (var mm in j["members"]) + { + DiscordMember member = JsonConvert.DeserializeObject(mm["user"].ToString()); + member.parentclient = this; + member.Roles = new List(); + JArray rawRoles = JArray.Parse(mm["roles"].ToString()); + if (rawRoles.Count > 0) + { + foreach (var role in rawRoles.Children()) + { + member.Roles.Add(temp.Roles.Find(x => x.ID == role.Value())); + } + } + else + { + member.Roles.Add(temp.Roles.Find(x => x.Name == "@everyone")); + } + temp.AddMember(member); + } + if (!j["presences"].IsNullOrEmpty()) + { + foreach (var presence in j["presences"]) + { + DiscordMember member = temp.GetMemberByKey(presence["user"]["id"].ToString()); + if (member != null) + { + member.SetPresence(presence["status"].ToString()); + if (!presence["game"].IsNullOrEmpty()) + { + member.CurrentGame = presence["game"]["name"].ToString(); + if (presence["game"]["type"].ToObject() == 1) + { + member.Streaming = true; + if (presence["game"]["url"].ToString() != null) + member.StreamURL = presence["game"]["url"].ToString(); + } + } + } + } + } + temp.Region = j["region"].ToString(); + temp.Owner = temp.GetMemberByKey(j["owner_id"].ToString()); + ServersList.Add(temp); + } + if (PrivateChannels == null) + PrivateChannels = new List(); + foreach (JObject privateChannel in m["d"]["private_channels"]) + { + foreach (JObject recepient in privateChannel["recipients"]) + { + DiscordPrivateChannel tempPrivate = JsonConvert.DeserializeObject(privateChannel.ToString()); + tempPrivate.Client = this; + tempPrivate.user_id = recepient["id"].ToString(); + DiscordServer potentialServer = new DiscordServer(); + ServersList.ForEach(x => + { + if (x.GetMemberByKey(recepient["id"].ToString()) != null) + { + potentialServer = x; + } + }); + if (potentialServer.Owner != null) //should be a safe test..i hope + { + DiscordMember recipient = potentialServer.GetMemberByKey(recepient["id"].ToString()); + if (recipient != null) + { + tempPrivate.Recipient = recipient; + } + else + { + DebugLogger.Log("Recipient was null!!!!", MessageLevel.Critical); + } + } + else + { + DebugLogger.Log("No potential server found for user's private channel null! This will probably fix itself.", MessageLevel.Debug); + } + PrivateChannels.Add(tempPrivate); + } + + } + + } + + /// + /// Sends an http DELETE request to leave the server you send in this parameter. + /// + /// The DiscordServer object you want to leave. + public void LeaveServer(DiscordServer server) => LeaveServer(server.ID); + + /// + /// (Owner only, non-bot only) Sends an http DELETE request to delete the server you specify. + /// + /// The DiscordServer object you want to delete. + public void DeleteServer(DiscordServer server) => DeleteServer(server.ID); + + /// + /// (Owner only, non-bot only) Sends an http DELETE request to delete the server you specify. + /// + /// The server's ID you want to delete. + public void LeaveServer(string ServerID) + { + string url = //Endpoints.BaseAPI + Endpoints.Guilds + $"/{ServerID}"; + Endpoints.BaseAPI + Endpoints.Users + Endpoints.Me + Endpoints.Guilds + $"/{ServerID}"; //old, left for lulz + try + { + WebWrapper.Delete(url, token); + } + catch (Exception ex) + { + DebugLogger.Log($"Error ocurred while leaving server ({ServerID}): {ex.Message}", MessageLevel.Error); + } + } + + /// + /// (Owner only, non-bot only) Sends an http DELETE request to delete the server you specify by ID. + /// + /// The server's ID you want to delete. + public void DeleteServer(string ServerID) + { + if (IsBotAccount) + throw new Exception("Bot accounts can't own servers!"); + + string url = Endpoints.BaseAPI + Endpoints.Guilds + $"/{ServerID}"; + try + { + WebWrapper.Delete(url, token); + } + catch (Exception ex) + { + DebugLogger.Log($"Error ocurred while deleting server ({ServerID}): {ex.Message}", MessageLevel.Error); + } + } + + + /// + /// Sends a message to a channel, what else did you expect? + /// + /// The text to send + /// DiscordChannel object to send the message to. + /// A DiscordMessage object of the message sent to Discord. + public DiscordMessage SendMessageToChannel(string message, DiscordChannel channel) + { + string url = Endpoints.BaseAPI + Endpoints.Channels + $"/{channel.ID}" + Endpoints.Messages; + try + { + JObject result = JObject.Parse(WebWrapper.Post(url, token, JsonConvert.SerializeObject(Utils.GenerateMessage(message)))); + if (result["content"].IsNullOrEmpty()) + throw new InvalidOperationException("Request returned a blank message, you may not have permission to send messages yet!"); + + DiscordMessage m = new DiscordMessage + { + ID = result["id"].ToString(), + Attachments = result["attachments"].ToObject(), + Author = channel.Parent.GetMemberByKey(result["author"]["id"].ToString()), + channel = channel, + TypeOfChannelObject = channel.GetType(), + Content = result["content"].ToString(), + RawJson = result, + timestamp = result["timestamp"].ToObject() + }; + return m; + } + catch (Exception ex) + { + DebugLogger.Log($"Error ocurred while sending message to channel ({channel.Name}): {ex.Message}", MessageLevel.Error); + } + return null; + } + + /// + /// Sends a file to the specified DiscordChannel with the given message. + /// + /// The channel to send the message to. + /// The message you want the file to have with it. + /// The path to the file you wish to send (be careful!) + public void AttachFile(DiscordChannel channel, string message, string pathToFile) + { + string url = Endpoints.BaseAPI + Endpoints.Channels + $"/{channel.ID}" + Endpoints.Messages; + //WebWrapper.PostWithAttachment(url, message, pathToFile); + try + { + var uploadResult = JObject.Parse(WebWrapper.HttpUploadFile(url, token, pathToFile, "file", "image/jpeg", null)); + + if (!string.IsNullOrEmpty(message)) + EditMessage(uploadResult["id"].ToString(), message, channel); + } + catch (Exception ex) + { + DebugLogger.Log($"Error ocurred while sending file ({pathToFile}) to {channel.Name}: {ex.Message}", MessageLevel.Error); + } + } + + /// + /// Sends a file to the specified DiscordChannel with the given message. + /// + /// The channel to send the message to. + /// The message you want the file to have with it. + /// A stream object to send the bytes from. + public void AttachFile(DiscordChannel channel, string message, System.IO.Stream stream) + { + string url = Endpoints.BaseAPI + Endpoints.Channels + $"/{channel.ID}" + Endpoints.Messages; + //WebWrapper.PostWithAttachment(url, message, pathToFile); + try + { + var uploadResult = JObject.Parse(WebWrapper.HttpUploadFile(url, token, stream, "file", "image/jpeg", null)); + + if (!string.IsNullOrEmpty(message)) + EditMessage(uploadResult["id"].ToString(), message, channel); + } + catch (Exception ex) + { + DebugLogger.Log($"Error ocurred while sending file by stream to {channel.Name}: {ex.Message}", MessageLevel.Error); + } + } + + /// + /// Changes the current client's avatar. + /// Any high resolution pictures are automatically downscaled and Discord will perform jpeg compression on them. + /// + /// The Bitmap object assosciated with the avatar you wish to upload. + public void ChangeClientAvatar(Bitmap image) + { + string base64 = Convert.ToBase64String(Utils.ImageToByteArray(image)); + string type = "image/jpeg;base64"; + string req = $"data:{type},{base64}"; + string usernameRequestJson = JsonConvert.SerializeObject(new + { + avatar = req, + email = ClientPrivateInformation.Email, + password = ClientPrivateInformation.Password, + username = ClientPrivateInformation.Username + }); + string url = Endpoints.BaseAPI + Endpoints.Users + "/@me"; + try + { + WebWrapper.Patch(url, token, usernameRequestJson); + } + catch (Exception ex) + { + DebugLogger.Log($"Error ocurred while changing client's avatar: {ex.Message}", MessageLevel.Error); + } + } + + /// + /// Changes the icon assosciated with the guild. Discord will perform jpeg compression and this image is automatically downscaled. + /// + /// The bitmap object associated + /// The guild of the icon you wish to change. + public void ChangeGuildIcon(Bitmap image, DiscordServer guild) + { + Bitmap resized = new Bitmap((Image)image, 200, 200); + + string base64 = Convert.ToBase64String(Utils.ImageToByteArray(resized)); + string type = "image/jpeg;base64"; + string req = $"data:{type},{base64}"; + string guildjson = JsonConvert.SerializeObject(new { icon = req, name = guild.Name }); + string url = Endpoints.BaseAPI + Endpoints.Guilds + "/" + guild.ID; + try + { + var result = JObject.Parse(WebWrapper.Patch(url, token, guildjson)); + } + catch (Exception ex) + { + DebugLogger.Log($"Error ocurred while changing guild {guild.Name}'s icon: {ex.Message}", MessageLevel.Error); + } + } + + /// + /// Returns a List of DiscordMessages. + /// + /// The channel to return them from. + /// How many to return + /// Messages before this message ID. + /// Messages after this message ID. + /// A List of DiscordMessages that you can iterate through. + public List GetMessageHistory(DiscordChannelBase channel, int count, string idBefore = "", string idAfter = "") + { + string request = "https://discordapp.com/api/channels/" + channel.ID + $"/messages?&limit={count}"; + if (!string.IsNullOrEmpty(idBefore)) + request += $"&before={idBefore}"; + if (string.IsNullOrEmpty(idAfter)) + request += $"&after={idAfter}"; + + JArray result = null; + + try + { + string res = WebWrapper.Get(request, token); + result = JArray.Parse(res); + } + catch (Exception ex) + { + DebugLogger.Log($"Error ocurred while getting message history for channel {channel.ID}: {ex.Message}", MessageLevel.Error); + } + + if (result != null) + { + List messageList = new List(); + /// NOTE + /// For some reason, the d object is excluded from this. + foreach (var item in result.Children()) + { + messageList.Add(new DiscordMessage + { + ID = item["id"].ToString(), + channel = channel, + Attachments = item["attachments"].ToObject(), + TypeOfChannelObject = channel.GetType(), + Author = GetMemberFromChannel(channel, item["author"]["id"].ToString()), + Content = item["content"].ToString(), + RawJson = item.ToObject(), + timestamp = DateTime.Parse(item["timestamp"].ToString()) + }); + } + return messageList; + } + + return null; + } + + /// + /// Changes the channel topic assosciated with the Discord text channel. + /// + /// The new channel topic. + /// The channel you wish to change the topic for. + public void ChangeChannelTopic(string Channeltopic, DiscordChannel channel) + { + string topicChangeJson = JsonConvert.SerializeObject( + new + { + name = channel.Name, + topic = Channeltopic + }); + string url = Endpoints.BaseAPI + Endpoints.Channels + $"/{channel.ID}"; + try + { + var result = JObject.Parse(WebWrapper.Patch(url, token, topicChangeJson)); + ServersList.Find(x => x.Channels.Find(y => y.ID == channel.ID) != null).Channels.Find(x => x.ID == channel.ID).Topic = Channeltopic; + } + catch (Exception ex) + { + DebugLogger.Log($"Error ocurred while changing channel topic for channel {channel.Name}: {ex.Message}", MessageLevel.Error); + } + } + + /* + public List GetRoles(DiscordServer server) + { + return null; + } + */ + + /// + /// Used for changing the client's email, password, username, etc. + /// + /// + public void ChangeClientInformation(DiscordUserInformation info) + { + string usernameRequestJson; + if (info.Password != ClientPrivateInformation.Password) + { + usernameRequestJson = JsonConvert.SerializeObject(new + { + email = info.Email, + new_password = info.Password, + password = ClientPrivateInformation.Password, + username = info.Username, + avatar = info.Avatar + }); + ClientPrivateInformation.Password = info.Password; + try + { + File.Delete("token_cache"); + DebugLogger.Log("Deleted token_cache due to change of password."); + } + catch (Exception) { /*ignore*/ } + } + else + { + usernameRequestJson = JsonConvert.SerializeObject(new + { + email = info.Email, + password = info.Password, + username = info.Username, + avatar = info.Avatar + }); + } + + string url = Endpoints.BaseAPI + Endpoints.Users + "/@me"; + try + { + var result = JObject.Parse(WebWrapper.Patch(url, token, usernameRequestJson)); + foreach (var server in ServersList) + { + if (server.Members[Me.ID] != null) + server.Members[Me.ID].Username = info.Username; + } + Me.Username = info.Username; + Me.Email = info.Email; + Me.Avatar = info.Avatar; + } + catch (Exception ex) + { + DebugLogger.Log($"Error ocurred while changing client's information: {ex.Message}", MessageLevel.Error); + } + } + + private void ChangeClientUsername(string newUsername) + { + string url = Endpoints.BaseAPI + Endpoints.Users + "/@me"; + string usernameRequestJson = JsonConvert.SerializeObject(new + { + email = ClientPrivateInformation.Email, + password = ClientPrivateInformation.Password, + username = newUsername, + avatar = Me.Avatar, + }); + try + { + var result = JObject.Parse(WebWrapper.Patch(url, token, usernameRequestJson)); + if (result != null) + { + foreach (var server in ServersList) + { + if (server.Members[Me.ID] != null) + server.Members[Me.ID].Username = newUsername; + } + Me.Username = newUsername; + } + } + catch (Exception ex) + { + DebugLogger.Log($"Error ocurred while changing client's username: {ex.Message}", MessageLevel.Error); + } + } + + /// + /// Sends a private message to the given user. + /// + /// The message text to send them. + /// The member you want to send this to. + /// + public DiscordMessage SendMessageToUser(string message, DiscordMember member) + { + string url = Endpoints.BaseAPI + Endpoints.Users + $"/{Me.ID}" + Endpoints.Channels; + string initMessage = "{\"recipient_id\":" + member.ID + "}"; + + try + { + var result = JObject.Parse(WebWrapper.Post(url, token, initMessage)); + if (result != null) + { + DiscordMember recipient = ServersList.Find( + x => x.GetMemberByKey(result["recipient"]["id"].ToString()) != null).Members[result["recipient"]["id"].ToString()]; + return SendActualMessage(result["id"].ToString(), message, recipient); + } + } + catch (Exception ex) + { + DebugLogger.Log($"Error ocurred while sending message to user, step 1: {ex.Message}", MessageLevel.Error); + } + + return null; + } + + private DiscordMessage SendActualMessage(string id, string message, DiscordMember recipient) + { + string url = Endpoints.BaseAPI + Endpoints.Channels + $"/{id}" + Endpoints.Messages; + DiscordMessage toSend = Utils.GenerateMessage(message); + + try + { + var result = JObject.Parse(WebWrapper.Post(url, token, JsonConvert.SerializeObject(toSend).ToString())); + DiscordMessage d = JsonConvert.DeserializeObject(result.ToString()); + d.Recipient = recipient; + d.channel = PrivateChannels.Find(x => x.ID == result["channel_id"].ToString()); + d.TypeOfChannelObject = typeof(DiscordPrivateChannel); + d.Author = Me; + return d; + } + catch (Exception ex) + { + DebugLogger.Log($"Error ocurred while sending message to user, step 2: {ex.Message}", MessageLevel.Error); + } + return null; + } + + /// + /// Gets the string value of the current game your bot is 'playing'. + /// + public string GetCurrentGame => CurrentGameName; + + /// + /// Returns true if the websocket is not null and is alive. + /// + public bool WebsocketAlive => (ws != null) ? ws.IsAlive : false; + + public bool ReadyComplete { get; private set; } + + #region Message Received Crap.. + + /// + /// Updates the bot's 'Currently playing' status to the following text. Pass in null if you want to remove this. + /// + /// The game's name. Old gameid lookup can be seen at: http://hastebin.com/azijiyaboc.json/ + /// Whether or not you want your bot to appear as if it is streaming. True means it will show it's streaming. + /// The 'url' for the stream, if your bot is streaming. + public async void UpdateCurrentGame(string gameName, bool streaming, string url = null) + { + string msg; + if (gameName.ToLower().Trim() != "") + { + msg = JsonConvert.SerializeObject( + new + { + op = 3, + d = new + { + idle_since = IdleSinceUnixTime == null ? (object)null : IdleSinceUnixTime, + game = new + { + name = gameName, + type = streaming ? 1 : 0, + url = (url != null) ? url : (object)null + } + } + }); + CurrentGameName = gameName; + DebugLogger.Log($"Updating client's current game as '{gameName}'"); + } + else + { + msg = JsonConvert.SerializeObject( + new + { + op = 3, + d = new + { + idle_since = IdleSinceUnixTime == null ? (object)null : IdleSinceUnixTime, + game = (object)null + } + }); + DebugLogger.Log("Setting current game to null."); + } + await ws.SendMessage(msg.ToString()); + } + + /// + /// Updates the bot's status. + /// + /// True if you want the bot to report as idle. + public async void UpdateBotStatus(bool idle) + { + string msg; + msg = JsonConvert.SerializeObject( + new + { + op = 3, + d = new + { + idle_since = idle ? (int)(DateTime.UtcNow - epoch).TotalMilliseconds : (object)null, + game = CurrentGameName.ToLower().Trim() == "" ? (object)null : new { name = CurrentGameName } + } + }); + await ws.SendMessage(msg.ToString()); //let's try it! + } + + private void PresenceUpdateEvents(JObject message) + { + DiscordPresenceUpdateEventArgs dpuea = new DiscordPresenceUpdateEventArgs(); + dpuea.RawJson = message; + + if (!message["d"]["guild_id"].IsNullOrEmpty()) + { + var server = ServersList.Find(x => x.ID == message["d"]["guild_id"].ToString()); + if (server != null) + { + var user = server.GetMemberByKey(message["d"]["user"]["id"].ToString().Trim()); + if (user != null) + { + //If usernames change. + if (!message["d"]["user"]["username"].IsNullOrEmpty()) + user.Username = message["d"]["user"]["username"].ToString(); + + //If avatar changes. + if (!message["d"]["user"]["avatar"].IsNullOrEmpty()) + user.Avatar = message["d"]["user"]["avatar"].ToString(); + + if (message["d"]["nick"].ToString() == null) + user.Nickname = null; + else + user.Nickname = message["d"]["nick"].ToString(); + + //Actual presence update + user.SetPresence(message["d"]["status"].ToString()); + + //Updating games. + string game = message["d"]["game"].ToString(); + if (message["d"]["game"].IsNullOrEmpty()) //null means not playing + { + dpuea.Game = ""; + user.CurrentGame = null; + } + else + { + if (message["d"]["game"]["name"].IsNullOrEmpty()) + if (message["d"]["game"]["game"].IsNullOrEmpty()) + dpuea.Game = ""; + else + dpuea.Game = message["d"]["game"]["game"].ToString(); + else + dpuea.Game = message["d"]["game"]["name"].ToString(); + user.CurrentGame = dpuea.Game; + + if (message["d"]["game"]["type"] != null && message["d"]["game"]["type"].ToObject() == 1) + { + user.Streaming = true; + if (message["d"]["game"]["url"].ToString() != null) + user.StreamURL = message["d"]["game"]["url"].ToString(); + } + } + dpuea.User = user; + + if (message["d"]["status"].ToString() == "online") + dpuea.Status = DiscordUserStatus.ONLINE; + else if (message["d"]["status"].ToString() == "idle") + dpuea.Status = DiscordUserStatus.IDLE; + else if (message["d"]["status"].ToString() == null || message["d"]["status"].ToString() == "offline") + dpuea.Status = DiscordUserStatus.OFFLINE; + if (PresenceUpdated != null) + PresenceUpdated(this, dpuea); + } + else + { + if (!message["d"]["guild_id"].IsNullOrEmpty()) //if this is null or empty, that means this pertains to friends list + { + if (!message["d"]["user"]["username"].IsNullOrEmpty() && !message["d"]["user"]["id"].IsNullOrEmpty()) + { + DebugLogger.Log($"User {message["d"]["user"]["username"]} ({message["d"]["user"]["id"].ToString()}) doesn't exist in server {server.Name} ({server.ID}) no problemo. Creating/adding", MessageLevel.Debug); + DiscordMember memeber = JsonConvert.DeserializeObject(message["d"]["user"].ToString()); + memeber.parentclient = this; + memeber.SetPresence(message["d"]["status"].ToString()); + memeber.Parent = ServersList.Find(x => x.ID == message["d"]["guild_id"].ToString()); + + if (message["d"]["game"].IsNullOrEmpty()) + { + dpuea.Game = ""; + memeber.CurrentGame = null; + } + else + { + dpuea.Game = message["d"]["game"]["name"].ToString(); + memeber.CurrentGame = dpuea.Game; + if (message["d"]["game"]["type"].ToObject() == 1) + { + user.Streaming = true; + if (message["d"]["game"]["url"].ToString() != null) + user.StreamURL = message["d"]["game"]["url"].ToString(); + } + } + + if (message["d"]["status"].ToString() == "online") + dpuea.Status = DiscordUserStatus.ONLINE; + else if (message["d"]["status"].ToString() == "idle") + dpuea.Status = DiscordUserStatus.IDLE; + else if (message["d"]["status"].ToString() == null || message["d"]["status"].ToString() == "offline") + dpuea.Status = DiscordUserStatus.OFFLINE; + + memeber.Parent.AddMember(memeber); + } + } + } + } + } + } + + + /// + /// Deletes a message with a specified ID. + /// This method will only work if the message was sent since the bot has ran. + /// + /// + public void DeleteMessage(string id) + { + var message = MessageLog[id]; + if (message != null) + SendDeleteRequest(message); + } + + /// + /// Deletes a specified DiscordMessage. + /// + /// + public void DeleteMessage(DiscordMessage message) + { + SendDeleteRequest(message); + } + + //public void DeletePrivateMessage(DiscordMessage message) + //{ + // SendDeleteRequest(message, true); + //} + + /// + /// Deletes all messages made by the bot since running. + /// + /// A count of messages deleted. + public int DeleteAllMessages() + { + int count = 0; + + foreach (var kvp in MessageLog) + { + if (kvp.Value.Author.ID == Me.ID) + { + SendDeleteRequest(kvp.Value); + count++; + } + } + return count; + } + + /// + /// Deletes the specified number of messages in a given channel. + /// Thank you to Siegen for this idea/method! + /// + /// The channel to delete messages in. + /// The amount of messages to delete (max 100) + /// The count of messages deleted. + public int DeleteMultipleMessagesInChannel(DiscordChannel channel, int count) + { + if (count > 100) + count = 100; + + int __count = 0; + + var messages = GetMessageHistory(channel, count, null, null); + + messages.ForEach(x => + { + if (x.channel.ID == channel.ID) + { + SendDeleteRequest(x); + __count++; + } + }); + + return __count; + } + + /// + /// + /// + /// + /// + /// + /// + public DiscordMember GetMemberFromChannel(DiscordChannelBase channel, string username, bool caseSensitive) + { + if (string.IsNullOrEmpty(username)) + throw new ArgumentException("Argument given for username was null/empty."); + if (channel != null) + { + if (channel.GetType() == typeof(DiscordChannel)) //regular channel + { + DiscordMember foundMember = ((DiscordChannel)channel).Parent.GetMemberByUsername(username, caseSensitive); + if (foundMember != null) + { + return foundMember; + } + else + { + DebugLogger.Log("Error in GetMemberFromChannel: foundMember was null!", MessageLevel.Error); + } + } + else if (channel.GetType() == typeof(DiscordPrivateChannel)) + { + return ((DiscordPrivateChannel)channel).Recipient; + } + } + else + { + DebugLogger.Log("Error in GetMemberFromChannel: channel was null!", MessageLevel.Error); + } + return null; + } + + /// + /// + /// + /// + /// + /// + public DiscordMember GetMemberFromChannel(DiscordChannelBase channel, string id) + { + if (channel != null) + { + if (channel.GetType() == typeof(DiscordChannel)) //regular + { + + DiscordMember foundMember = ((DiscordChannel)channel).Parent.GetMemberByKey(id); + if (foundMember != null) + return foundMember; + else + { + DebugLogger.Log($"Error in GetMemberFromChannel: foundMember was null! ID: {id}", MessageLevel.Error); + } + } + else if (channel.GetType() == typeof(DiscordPrivateChannel)) + { + return ((DiscordPrivateChannel)channel).Recipient; + } + } + else + { + DebugLogger.Log("Error in GetMemberFromChannel: channel was null!", MessageLevel.Error); + } + return null; + } + + /// + /// you probably shouldn't use this. + /// + /// + /// + public DiscordChannel GetChannelByName(string channelName) + { + DiscordServer findServer = ServersList.Where(x => x.Channels.Find(y => y.Name.ToLower() == channelName.ToLower()) != null).FirstOrDefault(); + if (findServer != null) + { + return findServer.Channels.Where(x => x.Name.ToLower() == channelName.ToLower()).FirstOrDefault(); + } + return null; + } + + /// + /// + /// + /// + /// + public DiscordChannel GetChannelByID(long id) + { + foreach (DiscordServer server in ServersList) + { + foreach (DiscordChannel channel in server.Channels) + { + if (channel.ID != null && channel.ID == id.ToString()) + { + return channel; + } + } + } + return null; + } + + public DiscordServer GetServerByChannelID(long id) + { + foreach (DiscordServer server in ServersList) + { + foreach (DiscordChannel channel in server.Channels) + { + if (channel.ID != null && channel.ID == id.ToString()) + { + return server; + } + } + } + return null; + } + + /// + /// (Client account only) accepts an invite to a server. + /// + /// The ID of the invite you want to accept. This is NOT the full URL of the invite + public void AcceptInvite(string inviteID) + { + if (!IsBotAccount) + { + if (inviteID.StartsWith("http://")) + inviteID = inviteID.Substring(inviteID.LastIndexOf('/') + 1); + + string url = Endpoints.BaseAPI + Endpoints.Invite + $"/{inviteID}"; + try + { + var result = WebWrapper.Post(url, token, "", true); + DebugLogger.Log("Accept invite result: " + result.ToString()); + } + catch (Exception ex) + { + DebugLogger.Log($"Error accepting invite: {ex.Message}", MessageLevel.Error); + } + } + else + throw new InvalidOperationException("Bot accounts can't accept invites normally! Please use the OAuth flow to add bots to servers you have the \"Manage Server\" permission in."); + } + + /// + /// + /// + /// The last DiscordMessage sent + public DiscordMessage GetLastMessageSent() + { + foreach (var message in MessageLog) + { + if (message.Value.Author.ID == Me.ID) + { + return message.Value; + } + } + return null; + } + + /// + /// + /// + /// + /// The last DiscordMessage sent in the given channel + public DiscordMessage GetLastMessageSent(DiscordChannel inChannel) + { + foreach (var message in MessageLog) + { + if (message.Value.Author.ID == Me.ID && message.Value.channel.ID == inChannel.ID) + { + return message.Value; + } + } + return null; + } + + /// + /// If you screwed up, you can use this method to edit a given message. This sends out an http patch request with a replacement message + /// + /// The ID of the message you want to edit. + /// What you want the text to be edited to. + /// The channel the message is in + /// the new and improved DiscordMessage object. + public DiscordMessage EditMessage(string MessageID, string replacementMessage, DiscordChannel channel) + { + string url = Endpoints.BaseAPI + Endpoints.Channels + $"/{channel.ID}" + Endpoints.Messages + $"/{MessageID}"; + try + { + string replacement = JsonConvert.SerializeObject( + new + { + content = replacementMessage, + mentions = new string[0] + } + ); + JObject result = JObject.Parse(WebWrapper.Patch(url, token, replacement)); + + DiscordMessage m = new DiscordMessage + { + RawJson = result, + Attachments = result["attachments"].ToObject(), + Author = channel.Parent.GetMemberByKey(result["author"]["id"].ToString()), + TypeOfChannelObject = channel.GetType(), + channel = channel, + Content = result["content"].ToString(), + ID = result["id"].ToString(), + timestamp = result["timestamp"].ToObject() + }; + return m; + } + catch (Exception ex) + { + DebugLogger.Log("Exception ocurred while editing: " + ex.Message, MessageLevel.Error); + } + + return null; + } + + private void SendDeleteRequest(DiscordMessage message) + { + string url; + url = Endpoints.BaseAPI + Endpoints.Channels + $"/{message.channel.ID}" + Endpoints.Messages + $"/{message.ID}"; + try + { + var result = WebWrapper.Delete(url, token); + } + catch (Exception ex) + { + DebugLogger.Log($"Exception ocurred while deleting message (ID: {message.ID}): " + ex.Message, MessageLevel.Error); + } + } + + private DiscordMessage FindInMessageLog(String id) + { + foreach (var message in MessageLog) + if (message.Key == id) + return message.Value; + + return null; + } + + private void MessageUpdateEvents(JObject message) + { + try + { + DiscordServer pserver = ServersList.Find(x => x.Channels.Find(y => y.ID == message["d"]["channel_id"].ToString()) != null); + DiscordChannel pchannel = pserver.Channels.Find(x => x.ID == message["d"]["channel_id"].ToString()); + if (pchannel != null) + { + if (message["d"]["author"] != null) + { + var toRemove = FindInMessageLog(message["d"]["id"].ToString()); + if (toRemove == null) + return; //No message exists + var jsonToEdit = toRemove.RawJson; + jsonToEdit["d"]["content"].Replace(JToken.FromObject(message["d"]["content"].ToString())); + if (MessageEdited != null) + MessageEdited(this, new DiscordMessageEditedEventArgs + { + Author = pserver.GetMemberByKey(message["d"]["author"]["id"].ToString()), + Channel = pchannel, + MessageText = message["d"]["content"].ToString(), + MessageType = DiscordMessageType.CHANNEL, + MessageEdited = new DiscordMessage + { + Author = pserver.GetMemberByKey(message["d"]["author"]["id"].ToString()), + Content = toRemove.Content, + Attachments = message["d"]["attachments"].ToObject(), + channel = pserver.Channels.Find(x => x.ID == message["d"]["channel_id"].ToString()), + RawJson = message, + ID = message["d"]["id"].ToString(), + timestamp = message["d"]["timestamp"].ToObject(), + }, + EditedTimestamp = message["d"]["edited_timestamp"].ToObject() + }); + MessageLog.Remove(message["d"]["id"].ToString()); + + DiscordMessage newMessage = toRemove; + newMessage.Content = jsonToEdit["d"]["content"].ToString(); + MessageLog.Add(message["d"]["id"].ToString(), newMessage); + + } + else //I know they say assume makes an ass out of you and me...but we're assuming it's Discord's weird auto edit of a just URL message + { + if (URLMessageAutoUpdate != null) + { + DiscordURLUpdateEventArgs asdf = new DiscordURLUpdateEventArgs(); //I'm running out of clever names and should probably split these off into different internal voids soon... + asdf.ID = message["d"]["id"].ToString(); + asdf.Channel = ServersList.Find(x => x.Channels.Find(y => y.ID == message["d"]["channel_id"].ToString()) != null).Channels.Find(x => x.ID == message["d"]["channel_id"].ToString()); + foreach (var embed in message["d"]["embeds"]) + { + DiscordEmbeds temp = new DiscordEmbeds(); + temp.URL = embed["url"].ToString(); + temp.Description = embed["description"].ToString(); + try + { + temp.ProviderName = embed["provider"]["name"] == null ? null : embed["provider"]["name"].ToString(); + temp.ProviderURL = embed["provider"]["url"].ToString(); + } + catch { }//noprovider + temp.Title = embed["title"].ToString(); + temp.Type = embed["type"].ToString(); + asdf.Embeds.Add(temp); + } + URLMessageAutoUpdate(this, asdf); + } + } + } + else + { + DebugLogger.Log("Couldn't find channel!", MessageLevel.Critical); + } + } + catch (Exception ex) + { + DebugLogger.Log($"Exception during MessageUpdateEvents.\n\tMessage: {ex.Message}\n\tStack: {ex.StackTrace}", MessageLevel.Critical); + } + } + + private DiscordChannel GetDiscordChannelByID(string id) + { + DiscordChannel returnVal = new DiscordChannel { ID = "-1" }; + ServersList.ForEach(x => + { + x.Channels.ForEach(y => + { + if (y.ID == id) + returnVal = y; + }); + }); + if (returnVal.ID != "-1") + return returnVal; + else + return null; + } + + private void MessageCreateEvents(JObject message) + { + try + { + string tempChannelID = message["d"]["channel_id"].ToString(); + + //DiscordServer foundServerChannel = ServersList.Find(x => x.channels.Find(y => y.id == tempChannelID) != null); + DiscordChannel potentialChannel = GetDiscordChannelByID(message["d"]["channel_id"].ToString()); + if (potentialChannel == null) //private message create + { + if (message["d"]["author"]["id"].ToString() != Me.ID) + { + var foundPM = PrivateChannels.Find(x => x.ID == message["d"]["channel_id"].ToString()); + DiscordPrivateMessageEventArgs dpmea = new DiscordPrivateMessageEventArgs(); + dpmea.Channel = foundPM; + dpmea.Message = message["d"]["content"].ToString(); + DiscordMember tempMember = new DiscordMember(this); + tempMember.Username = message["d"]["author"]["username"].ToString(); + tempMember.ID = message["d"]["author"]["id"].ToString(); + dpmea.Author = tempMember; + tempMember.parentclient = this; + dpmea.RawJson = message; + + PrivateMessageReceived?.Invoke(this, dpmea); + } + else + { + //if (DebugMessageReceived != null) + // DebugMessageReceived(this, new DiscordDebugMessagesEventArgs { message = "Ignoring MESSAGE_CREATE for private channel for message sent from this client." }); + } + } + else + { + DiscordMessageEventArgs dmea = new DiscordMessageEventArgs(); + dmea.RawJson = message; + dmea.Channel = potentialChannel; + + dmea.MessageText = message["d"]["content"].ToString(); + + DiscordMember tempMember = null; + if (potentialChannel.Parent != null) // Server not sync-ed yet. We need to re-request data + { + tempMember = potentialChannel.Parent.GetMemberByKey(message["d"]["author"]["id"].ToString()); + if (tempMember == null) + { + tempMember = JsonConvert.DeserializeObject(message["author"].ToString()); + tempMember.parentclient = this; + tempMember.Parent = potentialChannel.Parent; + + potentialChannel.Parent.AddMember(tempMember); + } + + dmea.Author = tempMember; + + DiscordMessage m = new DiscordMessage(); + m.Author = dmea.Author; + m.channel = dmea.Channel; + m.TypeOfChannelObject = dmea.Channel.GetType(); + m.Content = dmea.MessageText; + m.ID = message["d"]["id"].ToString(); + m.RawJson = message; + m.timestamp = DateTime.Now; + dmea.Message = m; + if (!message["d"]["attachments"].IsNullOrEmpty()) + { + List tempList = new List(); + foreach (var attachment in message["d"]["attachments"]) + { + tempList.Add(JsonConvert.DeserializeObject(attachment.ToString())); + } + m.Attachments = tempList.ToArray(); + } + + if (!message["d"]["mentions"].IsNullOrEmpty()) + { + JArray mentionsAsArray = JArray.Parse(message["d"]["mentions"].ToString()); + foreach (var mention in mentionsAsArray) + { + string id = mention["id"].ToString(); + if (id.Equals(Me.ID)) + { + if (MentionReceived != null) + MentionReceived(this, dmea); + } + } + } + + KeyValuePair toAdd = new KeyValuePair(message["d"]["id"].ToString(), m); + MessageLog.Add(message["d"]["id"].ToString(), m); + + MessageReceived?.Invoke(this, dmea); + } + } + } + catch (Exception ex) + { + DebugLogger.Log(string.Format("Error ocurred during MessageCreateEvents: {0}\r\n{1}", ex.Message, message.ToString()), MessageLevel.Error); + } + } + + private void ChannelCreateEvents(JObject message) + { + /*{{ + "t": "CHANNEL_CREATE", + "s": 97, + "op": 0, + "d": { + "type": 1, + "recipients": [ + { + "username": "", + "id": "", + "discriminator": "8031", + "avatar": "" + } + ], + "last_message_id": null, + "id": "496435723788877835" + } +}}*/ + if (message["d"]["is_private"].ToString().ToLower() == "false") + { + var foundServer = ServersList.Find(x => x.ID == message["d"]["guild_id"].ToString()); + if (foundServer != null) + { + DiscordChannel tempChannel = new DiscordChannel(); + tempChannel.Client = this; + tempChannel.Name = message["d"]["name"].ToString(); + tempChannel.Type = message["d"]["type"].ToObject(); + if (tempChannel.Type == ChannelType.Voice && !message["d"]["bitrate"].IsNullOrEmpty()) + tempChannel.Bitrate = message["d"]["bitrate"].ToObject(); + + tempChannel.ID = message["d"]["id"].ToString(); + tempChannel.Parent = foundServer; + foundServer.Channels.Add(tempChannel); + + DiscordChannelCreateEventArgs fae = new DiscordChannelCreateEventArgs(); + fae.ChannelCreated = tempChannel; + fae.ChannelType = DiscordChannelCreateType.CHANNEL; + + ChannelCreated?.Invoke(this, fae); + } + } + else + { + DiscordPrivateChannel tempPrivate = new DiscordPrivateChannel(); + tempPrivate.Client = this; + tempPrivate.ID = message["d"]["id"].ToString(); + DiscordMember recipient = ServersList.Find(x => x.GetMemberByKey(message["d"]["recipient"]["id"].ToString()) != null).GetMemberByKey(message["d"]["recipient"]["id"].ToString()); + tempPrivate.Recipient = recipient; + PrivateChannels.Add(tempPrivate); + + DiscordPrivateChannelEventArgs fak = new DiscordPrivateChannelEventArgs + { + ChannelType = DiscordChannelCreateType.PRIVATE, + ChannelCreated = tempPrivate + }; + + PrivateChannelCreated?.Invoke(this, fak); + } + } + #endregion + private string GetGatewayUrl() + { + if (token == null) + throw new NullReferenceException("token was null!"); + + //i'm ashamed of myself for this but i'm tired + tryAgain: + string url = Endpoints.BaseAPI + Endpoints.Gateway; + if (V4Testing) + url = "https://ptb.discordapp.com/api/gateway"; + try + { + string gateway = JObject.Parse(WebWrapper.Get(url, token))["url"].ToString(); + if (!string.IsNullOrEmpty(gateway)) + { + return gateway + (V4Testing ? "?encoding=json&v=4" : ""); + } + else + throw new NullReferenceException("Failed to retrieve Gateway urL!"); + } + catch (UnauthorizedAccessException) //bad token + { + DebugLogger.Log("Got 401 from Discord. Token bad, deleting and retrying login..."); + if (File.Exists(((uint)StrippedEmail.GetHashCode()) + ".cache")) + { + File.Delete(((uint)StrippedEmail.GetHashCode()) + ".cache"); + } + SendLoginRequest(); + goto tryAgain; + } + catch (Exception ex) + { + DebugLogger.Log("Exception ocurred while retrieving Gateway URL: " + ex.Message, MessageLevel.Error); + return null; + } + } + + /// + /// + /// + /// + /// + public DiscordServer GetServerChannelIsIn(DiscordChannel channel) + { + return ServersList.Find(x => x.Channels.Find(y => y.ID == channel.ID) != null); + } + + /// + /// Deletes a specified Discord channel given you have the permission. + /// + /// The DiscordChannel object to delete + public void DeleteChannel(DiscordChannel channel) + { + string url = Endpoints.BaseAPI + Endpoints.Channels + $"/{channel.ID}"; + try + { + WebWrapper.Delete(url, token); + } + catch (Exception ex) + { + DebugLogger.Log("Exception ocurred while deleting channel: " + ex.Message, MessageLevel.Error); + } + } + + /// + /// Creates either a text or voice channel in a DiscordServer given a name. Given you have the permission of course. + /// + /// The server to create the channel in. + /// The name of the channel (will automatically be lowercased if text) + /// True if you want the channel to be a voice channel. + /// The newly created DiscordChannel + public DiscordChannel CreateChannel(DiscordServer server, string ChannelName, bool voice) + { + string url = Endpoints.BaseAPI + Endpoints.Guilds + $"/{server.ID}" + Endpoints.Channels; + var reqJson = JsonConvert.SerializeObject(new { name = ChannelName, type = voice ? "voice" : "text" }); + try + { + var result = JObject.Parse(WebWrapper.Post(url, token, reqJson)); + if (result != null) + { + DiscordChannel dc = new DiscordChannel + { + Client = this, + Name = result["name"].ToString(), + ID = result["id"].ToString(), + Type = result["type"].ToObject(), + Private = result["is_private"].ToObject(), + }; + if (!result["topic"].IsNullOrEmpty()) + dc.Topic = result["topic"].ToString(); + if (dc.Type == ChannelType.Voice && !result["bitrate"].IsNullOrEmpty()) + dc.Bitrate = result["bitrate"].ToObject(); + + server.Channels.Add(dc); + return dc; + } + } + catch (Exception ex) + { + DebugLogger.Log("Exception ocurred while creating channel: " + ex.Message, MessageLevel.Error); + } + return null; + } + + /// + /// Creates an empty guild with only this client in it given the following name. + /// Unknown if works on bot accounts or not. + /// + /// The name of the guild you wish to create. + /// the created DiscordServer + public DiscordServer CreateGuild(string GuildName) + { + string createGuildUrl = Endpoints.BaseAPI + Endpoints.Guilds; + string req = JsonConvert.SerializeObject(new { name = GuildName }); + + try + { + var response = JObject.Parse(WebWrapper.Post(createGuildUrl, token, req)); + if (response != null) + { + DiscordServer server = new DiscordServer(); + server.JoinedAt = response["joined_at"].ToObject(); + server.ID = response["id"].ToString(); + server.Name = response["name"].ToString(); + server.parentclient = this; + + string channelGuildUrl = createGuildUrl + $"/{server.ID}" + Endpoints.Channels; + var channelRespone = JArray.Parse(WebWrapper.Get(channelGuildUrl, token)); + foreach (var item in channelRespone.Children()) + { + server.Channels.Add(new DiscordChannel + { + Client = this, + Name = item["name"].ToString(), + ID = item["id"].ToString(), + Topic = item["topic"].ToString(), + Private = item["is_private"].ToObject(), + Type = item["type"].ToObject() + }); + } + + server.AddMember(Me); + server.Owner = server.GetMemberByKey(response["owner_id"].ToString()); + if (server.Owner == null) + DebugLogger.Log("Owner is null in CreateGuild!", MessageLevel.Critical); + + ServersList.Add(server); + return server; + } + } + catch (Exception ex) + { + DebugLogger.Log("Exception ocurred while creating guild: " + ex.Message, MessageLevel.Error); + } + return null; + } + + /// + /// Edits the name of the guild, given you have the permission. + /// + /// The guild's name you wish to edit. + /// The new guild name. + public void EditGuildName(DiscordServer guild, string NewGuildName) + { + string editGuildUrl = Endpoints.BaseAPI + Endpoints.Guilds + $"/{guild.ID}"; + var newNameJson = JsonConvert.SerializeObject(new { name = NewGuildName }); + try + { + WebWrapper.Patch(editGuildUrl, token, newNameJson); + } + catch (Exception ex) + { + DebugLogger.Log($"Exception ocurred while editing guild ({guild.Name}) name: " + ex.Message, MessageLevel.Error); + } + } + + /// + /// Assigns a specified role to a member, given you have the permission. + /// + /// The guild you and the user are in. + /// The role you wish to assign them. + /// The member you wish to assign the role to. + public void AssignRoleToMember(DiscordServer guild, DiscordRole role, DiscordMember member) + { + string url = Endpoints.BaseAPI + Endpoints.Guilds + $"/{guild.ID}" + Endpoints.Members + $"/{member.ID}"; + string message = JsonConvert.SerializeObject(new { roles = new string[] { role.ID } }); + try + { + WebWrapper.Patch(url, token, message); + } + catch (Exception ex) + { + DebugLogger.Log($"Exception ocurred while assigning role ({role.Name}) to member ({member.Username}): " + + ex.Message, MessageLevel.Error); + } + } + + /// + /// Assigns the specified roles to a member, given you have the permission. + /// + /// The guild you and the user are in. + /// The roles you wish to assign them. + /// The member you wish to assign the role to. + public void AssignRoleToMember(DiscordServer guild, List roles, DiscordMember member) + { + string url = Endpoints.BaseAPI + Endpoints.Guilds + $"/{guild.ID}" + Endpoints.Members + $"/{member.ID}"; + List rolesAsIds = new List(); + roles.ForEach(x => rolesAsIds.Add(x.ID)); + string message = JsonConvert.SerializeObject(new { roles = rolesAsIds.ToArray() }); + try + { + WebWrapper.Patch(url, token, message); + } + catch (Exception ex) + { + DebugLogger.Log($"Exception ocurred while assigning {roles.Count} role(s) to member ({member.Username}): " + + ex.Message, MessageLevel.Error); + } + } + + /// + /// Creates and invite to the given channel. + /// + /// + /// The invite's id. + public string CreateInvite(DiscordChannel channel) + { + string url = Endpoints.BaseAPI + Endpoints.Channels + $"/{channel.ID}" + Endpoints.Invites; + try + { + var resopnse = JObject.Parse(WebWrapper.Post(url, token, "{\"validate\":\"\"}")); + if (resopnse != null) + { + return resopnse["code"].ToString(); + } + } + catch (Exception ex) + { + DebugLogger.Log($"Error ocurred while creating invite for channel {channel.Name}: {ex.Message}", MessageLevel.Error); + } + return null; + } + + /// + /// Deletes an invite by id + /// + /// The ID of the invite you wish to delete. + public void DeleteInvite(string id) + { + string url = Endpoints.BaseAPI + Endpoints.Invites + $"/{id}"; + try + { + WebWrapper.Delete(url, token); + } + catch (Exception ex) + { + DebugLogger.Log($"Error ocurred while deleting invite: {ex.Message}", MessageLevel.Error); + } + } + + /// + /// Just prepends https://discord.gg/ to a given invite :) + /// + /// + /// A full invite URL. + public string MakeInviteURLFromCode(string id) => "https://discord.gg/" + id; + + + /// + /// Runs the websocket connection for the client hooking up the appropriate events. + /// + /// If true, DiscordSharp will connect using the .Net Framework's built-in WebSocketClasses. + /// Please do not use this on Mono or versions of Windows below 8/8.1 + public void Connect() + { + CurrentGatewayURL = GetGatewayUrl(); + if (string.IsNullOrEmpty(CurrentGatewayURL)) + { + DebugLogger.Log("Gateway URL was null or empty?!", MessageLevel.Critical); + return; + } + DebugLogger.Log("Gateway retrieved: " + CurrentGatewayURL); + + ws = new NetWebSocketWrapper(CurrentGatewayURL); + + ws.MessageReceived += (sender, e) => + { + try + { + var message = JObject.Parse(e.Message); + + if (EnableVerboseLogging) + if (message["t"].ToString() != "READY") + DebugLogger.Log(message.ToString(), MessageLevel.Unecessary); + + if (!message["t"].IsNullOrEmpty()) //contains a t parameter used for client events. + ClientPacketReceived(message); + else + MiscellaneousOpcodes(message); + + if (!message["s"].IsNullOrEmpty()) + Sequence = message["s"].ToObject(); + } + catch (Exception ex) + { + DebugLogger.Log($"MessageReceived Error: {ex.Message}\n\n```{e.Message}\n```\n", MessageLevel.Error); + return; + } + }; + ws.SocketOpened += (sender, e) => + { + SendIdentifyPacket(); + SocketOpened?.Invoke(this, null); + }; + ws.SocketClosed += (sender, e) => + { + DiscordSocketClosedEventArgs scev = new DiscordSocketClosedEventArgs(); + scev.Code = e.Code; + scev.Reason = e.Reason; + scev.WasClean = e.WasClean; + SocketClosed?.Invoke(this, scev); + + if (Autoconnect && !e.WasClean) + { + PerformReconnection(); + } + }; + ws.Connect(); + DebugLogger.Log("Connecting.."); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void MiscellaneousOpcodes(JObject message) + { + switch (message["op"].ToObject()) + { + case Opcodes.INVALIDATE_SESSION: + // TODO: the session was invalidated and a full reconnection must be performed. + DebugLogger.Log($"The session was invalidated. ", MessageLevel.Critical); + break; + } + } + + private void PerformReconnection() + { + string resumeJson = JsonConvert.SerializeObject(new + { + op = Opcodes.RESUME, + d = new + { + seq = Sequence, + token = DiscordClient.token, + session_id = SessionID + } + }); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private async void ClientPacketReceived(JObject message) + { + string header = message["t"].ToString(); + + Debug.WriteLine(string.Format("[DiscordClient] Received {0} HEADER.", header)); + + switch (header) + { + case "READY": + { + Sequence = message["s"].ToObject(); + DiscordGatewayVersion = message["d"]["v"].ToObject(); + if (message["d"]?["heartbeat_interval"] != null) + HeartbeatInterval = message["d"]["heartbeat_interval"].ToObject(); + BeginHeartbeatTask(); + + if (WriteLatestReady) + { + using (var sw = new StreamWriter("READY_LATEST.txt")) + { + sw.Write(message); + } + } + + Me = JsonConvert.DeserializeObject(message["d"]["user"].ToString()); + Me.parentclient = this; + IsBotAccount = message["d"]["user"]["bot"].IsNullOrEmpty() ? false : message["d"]["user"]["bot"].ToObject(); + ClientPrivateInformation.Avatar = Me.Avatar; + ClientPrivateInformation.Username = Me.Username; + GetChannelsList(message); + SessionID = message["d"]["session_id"].ToString(); + + //TESTING + string[] guildID = new string[ServersList.Count]; + for (int i = 0; i < guildID.Length; i++) + guildID[i] = ServersList[i].ID; + + if (RequestAllUsersOnStartup) + { + string wsChunkTest = JsonConvert.SerializeObject(new + { + op = 8, + d = new + { + guild_id = guildID, + query = "", + limit = 0 + } + }); + await ws.SendMessage(wsChunkTest); + + //ws.Send(@"{""op"":4,""d"":{ ""guild_id"":null,""channel_id"":null,""self_mute"":true,""self_deaf"":false,""self_video"":false}}"); + } + + ReadyComplete = true; + + await Task.Run(() => + { + Task.Delay(3000); + Connected?.Invoke(this, new DiscordConnectEventArgs { User = Me }); + }); //fire and forget waiting of up to 3 seconds for guilds to become available. + break; + } + case "GUILD_MEMBERS_CHUNK": + GuildMemberChunkEvents(message); + break; + case "GUILD_MEMBER_REMOVE": + GuildMemberRemoveEvents(message); + break; + case "GUILD_MEMBER_ADD": + GuildMemberAddEvents(message); + break; + case "GUILD_DELETE": + GuildDeleteEvents(message); + break; + case "GUILD_CREATE": + GuildCreateEvents(message); + break; + case "GUILD_MEMBER_UPDATE": + GuildMemberUpdateEvents(message); + break; + case "GUILD_UPDATE": + GuildUpdateEvents(message); + break; + case "GUILD_ROLE_DELETE": + GuildRoleDeleteEvents(message); + break; + case "GUILD_ROLE_UPDATE": + GuildRoleUpdateEvents(message); + break; + case "PRESENCE_UPDATE": + PresenceUpdateEvents(message); + break; + case "MESSAGE_UPDATE": + MessageUpdateEvents(message); + break; + case "TYPING_START": + DiscordServer server = ServersList.Find(x => x.Channels.Find(y => y.ID == message["d"]["channel_id"].ToString()) != null); + if (server != null) + { + DiscordChannel channel = server.Channels.Find(x => x.ID == message["d"]["channel_id"].ToString()); + DiscordMember uuser = server.GetMemberByKey(message["d"]["user_id"].ToString()); + UserTypingStart?.Invoke(this, new DiscordTypingStartEventArgs { user = uuser, Channel = channel, Timestamp = int.Parse(message["d"]["timestamp"].ToString()) }); + } + break; + case "MESSAGE_CREATE": + MessageCreateEvents(message); + break; + case "CHANNEL_CREATE": + ChannelCreateEvents(message); + break; + case "VOICE_STATE_UPDATE": + VoiceStateUpdateEvents(message); + break; + case "VOICE_SERVER_UPDATE": + VoiceServerUpdateEvents(message); + break; + case "MESSAGE_DELETE": + MessageDeletedEvents(message); + break; + case "USER_UPDATE": + UserUpdateEvents(message); + break; + case "CHANNEL_UPDATE": + ChannelUpdateEvents(message); + break; + case "CHANNEL_DELETE": + ChannelDeleteEvents(message); + break; + case "GUILD_BAN_ADD": + GuildMemberBannedEvents(message); + break; + case "GUILD_BAN_REMOVE": + GuildMemberBanRemovedEvents(message); + break; + case "MESSAGE_ACK": //ignore this message, it's irrelevant + break; + case "SESSIONS_REPLACE": // idk + default: + UnknownMessageTypeReceived?.Invoke(this, new UnknownMessageEventArgs { RawJson = message }); + break; + } + } + + private async void SendIdentifyPacket() + { + string initJson = JsonConvert.SerializeObject(new + { + op = 2, + d = new + { + v = 4, + token = token, + /*large_threshold = 50,*/ + properties = DiscordProperties, + + large_threshold = 100, + synced_guilds = DiscordSyncedGuilds, + presence = new + { + status = "online", + since = 0, + afk = false, + game = "null", + }, + compress = false + } + }); + + DebugLogger.Log("Sending initJson ( " + initJson + " )"); + + await ws.SendMessage(initJson); + } + + private void BeginHeartbeatTask() + { + KeepAliveTaskTokenSource = new CancellationTokenSource(); + KeepAliveTaskToken = KeepAliveTaskTokenSource.Token; + KeepAliveTask = new Task(() => + { + while (true) + { + DebugLogger.Log("Hello from inside KeepAliveTask!"); + Thread.Sleep(HeartbeatInterval); + KeepAlive(); + } + }, KeepAliveTaskToken); + KeepAliveTask.Start(); + DebugLogger.Log("Began keepalive task.."); + } + + private void GuildMemberChunkEvents(JObject message) + { + if (!message["d"]["members"].IsNullOrEmpty()) + { + DiscordServer inServer = ServersList.Find(x => x.ID == message["d"]["guild_id"].ToString()); + JArray membersAsArray = (JArray)message["d"]["members"]; + + Parallel.ForEach(membersAsArray, member => + { + string memberId = (string)member["user"]["id"]; + + DiscordMember existingMember = inServer.GetMemberByKey((string)member["user"]["id"]); + + if (existingMember == null) + { + existingMember = JsonConvert.DeserializeObject(member["user"].ToString()); + + if (!member["roles"].IsNullOrEmpty()) + { + JArray rollsArray = (JArray)member["roles"]; + if (rollsArray.Count > 0) + { + foreach (var rollID in rollsArray) + { + existingMember.Roles.Add(inServer.Roles.Find(x => x.ID == rollID.ToString())); + } + } + } + existingMember.Muted = member["mute"].ToObject(); + existingMember.Deaf = member["deaf"].ToObject(); + existingMember.Roles.Add(inServer.Roles.Find(x => x.Name == "@everyone")); + existingMember.Status = Status.Offline; + existingMember.parentclient = this; + existingMember.Parent = inServer; + inServer.AddMember(existingMember); + } + else + { + // does nothing, already in list + } + + ///Check private channels + DiscordPrivateChannel _channel = PrivateChannels.Find(x => x.user_id == existingMember.ID); + if (_channel != null) + { + DebugLogger.Log("Found user for private channel!", MessageLevel.Debug); + _channel.Recipient = existingMember; + } + }); + // Debug.WriteLine("Loaded Member size: " + membersAsArray.Count + " Total size: " + inServer.Members.Count); + + if (membersAsArray.Count != 1000) // chunks of 1000 sent at once. + { + GuildMembersLoadedEventArgs?.Invoke(this, new DiscordGuildMembersLoadedEventArgs() + { + Server = inServer, + MemberSize = inServer.Members.Count, + }); + } + } + } + + private void GuildMemberBanRemovedEvents(JObject message) + { + DiscordBanRemovedEventArgs e = new DiscordBanRemovedEventArgs(); + + e.Guild = ServersList.Find(x => x.ID == message["d"]["guild_id"].ToString()); + e.MemberStub = JsonConvert.DeserializeObject(message["d"]["user"].ToString()); + + BanRemoved?.Invoke(this, e); + } + + private void GuildMemberBannedEvents(JObject message) + { + DiscordGuildBanEventArgs e = new DiscordGuildBanEventArgs(); + e.Server = ServersList.Find(x => x.ID == message["d"]["guild_id"].ToString()); + if (e.Server != null) + { + e.MemberBanned = e.Server.GetMemberByKey(message["d"]["user"]["id"].ToString()); + if (e.MemberBanned != null) + { + if (GuildMemberBanned != null) + GuildMemberBanned(this, e); + ServersList.Find(x => x.ID == e.Server.ID).RemoveMember(e.MemberBanned.ID); + } + else + { + DebugLogger.Log("Error in GuildMemberBannedEvents: MemberBanned is null, attempting internal index of removed members.", MessageLevel.Error); + e.MemberBanned = RemovedMembers.Find(x => x.ID == message["d"]["user"]["id"].ToString()); + if (e.MemberBanned != null) + { + GuildMemberBanned?.Invoke(this, e); + } + else + { + DebugLogger.Log("Error in GuildMemberBannedEvents: MemberBanned is null, not even found in internal index!", MessageLevel.Error); + } + } + } + else + { + DebugLogger.Log("Error in GuildMemberBannedEvents: Server is null?!", MessageLevel.Error); + } + } + + private void VoiceServerUpdateEvents(JObject message) + { + // TODO VoiceClient is null when disconnecting from voice + if (VoiceClient == null) + { + return; + } + VoiceClient.VoiceEndpoint = message["d"]["endpoint"].ToString(); + VoiceClient.Token = message["d"]["token"].ToString(); + + VoiceClient.Guild = ServersList.Find(x => x.ID == message["d"]["guild_id"].ToString()); + VoiceClient.Me = Me; + + VoiceClient.PacketReceived += (sender, e) => + { + AudioPacketReceived?.Invoke(sender, e); + }; + + VoiceClient.DebugMessageReceived += (sender, e) => + { + VoiceClientDebugMessageReceived?.Invoke(this, e); + }; + + ConnectToVoiceAsync(); + } + +#if NETFX4_5 + private void ConnectToVoiceAsync() + { + VoiceClient.InitializeOpusEncoder(); + VoiceThread = new Thread(() => VoiceClient.Initiate()); + VoiceThread.Start(); + } +#else + private Task ConnectToVoiceAsync() + { + VoiceClient.InitializeOpusEncoder(); + return Task.Factory.StartNew(() => VoiceClient.Initiate()); + } +#endif + + /// + /// Kicks a specified DiscordMember from the guild that's assumed from their + /// parent property. + /// + /// + public void KickMember(DiscordMember member) + { + string url = Endpoints.BaseAPI + Endpoints.Guilds + $"/{member.Parent.ID}" + Endpoints.Members + $"/{member.ID}"; + try + { + WebWrapper.Delete(url, token); + } + catch (Exception ex) + { + DebugLogger.Log($"Error during KickMember\n\t{ex.Message}\n\t{ex.StackTrace}", MessageLevel.Error); + } + } + + /// + /// Bans a specified DiscordMember from the guild that's assumed from their + /// parent property. + /// + /// + /// The number of days the user should be banned for, or 0 for infinite. + public DiscordMember BanMember(DiscordMember member, int days = 0) + { + string url = Endpoints.BaseAPI + Endpoints.Guilds + $"/{member.Parent.ID}" + Endpoints.Bans + $"/{member.ID}"; + url += $"?delete-message-days={days}"; + try + { + WebWrapper.Put(url, token); + return member; + } + catch (Exception ex) + { + DebugLogger.Log($"Error during BanMember\n\t{ex.Message}\n\t{ex.StackTrace}", MessageLevel.Error); + return null; + } + } + + /// + /// Bans a specified DiscordMember from the guild that's assumed from their + /// parent property. + /// + /// + /// + /// + /// + public DiscordMember BanMember(DiscordMember member, DiscordServer serverOverride, int days = 0) + { + string url = Endpoints.BaseAPI + Endpoints.Guilds + $"/{serverOverride.ID}" + Endpoints.Bans + $"/{member.ID}"; + url += $"?delete-message-days={days}"; + try + { + WebWrapper.Put(url, token); + return member; + } + catch (Exception ex) + { + DebugLogger.Log($"Error during BanMember\n\t{ex.Message}\n\t{ex.StackTrace}", MessageLevel.Error); + return null; + } + } + + /// + /// Retrieves a DiscordMember List of members banned in the specified server. + /// + /// + /// Null if no permission. + public List GetBans(DiscordServer server) + { + List returnVal = new List(); + string url = Endpoints.BaseAPI + Endpoints.Guilds + $"/{server.ID}" + Endpoints.Bans; + try + { + var __res = WebWrapper.Get(url, token); + var permissionCheck = JObject.Parse(__res); + { + if (!permissionCheck["message"].IsNullOrEmpty()) + return null; //no permission + } + JArray response = JArray.Parse(__res); + if (response != null && response.Count > 0) + { + DebugLogger.Log($"Ban count: {response.Count}"); + + foreach (var memberStub in response) + { + DiscordMember temp = JsonConvert.DeserializeObject(memberStub["user"].ToString()); + if (temp != null) + returnVal.Add(temp); + else + DebugLogger.Log($"memberStub[\"user\"] was null?! Username: {memberStub["user"]["username"].ToString()} ID: {memberStub["user"]["username"].ToString()}", MessageLevel.Error); + } + } + else + return returnVal; + } + catch (Exception ex) + { + DebugLogger.Log($"An error ocurred while retrieving bans for server \"{server.Name}\"\n\tMessage: {ex.Message}\n\tStack: {ex.StackTrace}", + MessageLevel.Error); + } + return returnVal; + } + + /// + /// Removes a ban on the user. + /// + /// The guild to lift the ban from. + /// The ID of the user to lift the ban. + public void RemoveBan(DiscordServer guild, string userID) + { + string url = Endpoints.BaseAPI + Endpoints.Guilds + $"/{guild.ID}" + Endpoints.Bans + $"/{userID}"; + try + { + WebWrapper.Delete(url, token); + } + catch (Exception ex) + { + DebugLogger.Log($"Error during RemoveBan\n\tMessage: {ex.Message}\n\tStack: {ex.StackTrace}", MessageLevel.Error); + } + } + + /// + /// Removes a ban on the user. + /// + /// The guild to lift the ban from. + /// The DiscordMember object of the user to lift the ban from, assuming you have it. + public void RemoveBan(DiscordServer guild, DiscordMember member) + { + string url = Endpoints.BaseAPI + Endpoints.Guilds + $"/{guild.ID}" + Endpoints.Bans + $"/{member.ID}"; + try + { + WebWrapper.Delete(url, token); + } + catch (Exception ex) + { + DebugLogger.Log($"Error during RemoveBan\n\tMessage: {ex.Message}\n\tStack: {ex.StackTrace}", MessageLevel.Error); + } + } + + /// + /// Echoes a received audio packet back. + /// + /// + public void EchoPacket(DiscordAudioPacket packet) + { + if (VoiceClient != null && ConnectedToVoice()) + VoiceClient.EchoPacket(packet).Wait(); + } + + /// + /// Connects to a given voice channel. + /// + /// The channel to connect to. + /// The voice configuration to use. If null, default values will be used. + /// Whether or not the client will connect muted. Defaults to false. + /// Whether or not the client will connect deaf. Defaults to false. + public async void ConnectToVoiceChannel(DiscordChannel channel, DiscordVoiceConfig voiceConfig = null, bool clientMuted = false, bool clientDeaf = false) + { + if (channel.Type != ChannelType.Voice) + throw new InvalidOperationException($"Channel '{channel.ID}' is not a voice channel!"); + + if (ConnectedToVoice()) + DisconnectFromVoice(); + + if (VoiceClient == null) + { + if (voiceConfig == null) + { + VoiceClient = new DiscordVoiceClient(this, new DiscordVoiceConfig()); + } + else + VoiceClient = new DiscordVoiceClient(this, voiceConfig); + } + VoiceClient.Channel = channel; + VoiceClient.ErrorReceived += (sender, e) => + { + if (GetLastVoiceClientLogger != null) + { + GetLastVoiceClientLogger = VoiceClient.GetDebugLogger; + DisconnectFromVoice(); + } + }; + VoiceClient.UserSpeaking += (sender, e) => + { + if (UserSpeaking != null) + UserSpeaking(this, e); + }; + VoiceClient.VoiceConnectionComplete += (sender, e) => + { + if (VoiceClientConnected != null) + VoiceClientConnected(this, e); + }; + VoiceClient.QueueEmpty += (sender, e) => + { + VoiceQueueEmpty?.Invoke(this, e); + }; + + string joinVoicePayload = JsonConvert.SerializeObject(new + { + op = 4, + d = new + { + guild_id = channel.Parent.ID, + channel_id = channel.ID, + self_mute = clientMuted, + self_deaf = clientDeaf + } + }); + + await ws.SendMessage(joinVoicePayload); + } + + /// + /// Clears the internal message log cache + /// + /// The number of internal messages cleared. + public int ClearInternalMessageLog() + { + int totalCount = MessageLog.Count; + MessageLog.Clear(); + return totalCount; + } + + /// + /// Iterates through a server's members and removes offline users. + /// + /// + /// The amount of users cleared. + public int ClearOfflineUsersFromServer(DiscordServer server) + { + return server.ClearOfflineMembers(); + } + + /// + /// Also disposes + /// + public async void DisconnectFromVoice() + { + string disconnectMessage = JsonConvert.SerializeObject(new + { + op = 4, + d = new + { + guild_id = VoiceClient != null && VoiceClient.Channel != null ? VoiceClient.Channel.Parent.ID : (object)null, + channel_id = (object)null, + self_mute = true, + self_deaf = false + } + }); + if (VoiceClient != null) + { + try + { + VoiceClient.Dispose(); + VoiceClient = null; + + + await ws.SendMessage(disconnectMessage); + } + catch + { } + } + if (ws != null) + { + await ws.SendMessage(disconnectMessage); + } + VoiceClient = null; + if (VoiceThread != null) + VoiceThread.Abort(); + DebugLogger.Log($"Disconnected from voice. VoiceClient null: {VoiceClient == null}"); + } + + /// + /// + /// + /// The current VoiceClient or null. + public DiscordVoiceClient GetVoiceClient() + { + if (ConnectedToVoice() && VoiceClient != null) + return VoiceClient; + + return null; + } + + private void GuildMemberUpdateEvents(JObject message) + { + DiscordServer server = ServersList.Find(x => x.ID == message["d"]["guild_id"].ToString()); + + DiscordMember memberUpdated = server.GetMemberByKey(message["d"]["user"]["id"].ToString()); + if (memberUpdated != null) + { + memberUpdated.Username = message["d"]["user"]["username"].ToString(); + if (message["d"]["nick"] != null) + { + if (message["d"]["nick"].ToString() == null) + memberUpdated.Nickname = ""; //No nickname + else + memberUpdated.Nickname = message["d"]["nick"].ToString(); + } + + if (!message["d"]["user"]["avatar"].IsNullOrEmpty()) + memberUpdated.Avatar = message["d"]["user"]["avatar"].ToString(); + memberUpdated.Discriminator = message["d"]["user"]["discriminator"].ToString(); + memberUpdated.ID = message["d"]["user"]["id"].ToString(); + + foreach (var roles in message["d"]["roles"]) + { + memberUpdated.Roles.Add(server.Roles.Find(x => x.ID == roles.ToString())); + } + + server.AddMember(memberUpdated); + GuildMemberUpdated?.Invoke(this, new DiscordGuildMemberUpdateEventArgs { MemberUpdate = memberUpdated, RawJson = message, ServerUpdated = server }); + } + else + { + DebugLogger.Log("memberUpdated was null?!?!?!", MessageLevel.Debug); + } + } + + private void GuildRoleUpdateEvents(JObject message) + { + DiscordServer inServer = ServersList.Find(x => x.ID == message["d"]["guild_id"].ToString()); + DiscordRole roleUpdated = new DiscordRole + { + Name = message["d"]["role"]["name"].ToString(), + Position = message["d"]["role"]["position"].ToObject(), + Permissions = new DiscordPermission(message["d"]["role"]["permissions"].ToObject()), + Managed = message["d"]["role"]["managed"].ToObject(), + Hoist = message["d"]["role"]["hoist"].ToObject(), + Color = new Color(message["d"]["role"]["color"].ToObject().ToString("x")), + ID = message["d"]["role"]["id"].ToString(), + }; + + ServersList.Find(x => x.ID == inServer.ID).Roles.Remove(ServersList.Find(x => x.ID == inServer.ID).Roles.Find(y => y.ID == roleUpdated.ID)); + ServersList.Find(x => x.ID == inServer.ID).Roles.Add(roleUpdated); + + RoleUpdated?.Invoke(this, new DiscordGuildRoleUpdateEventArgs { RawJson = message, RoleUpdated = roleUpdated, InServer = inServer }); + } + + private void GuildRoleDeleteEvents(JObject message) + { + DiscordServer inServer = ServersList.Find(x => x.ID == message["d"]["guild_id"].ToString()); + DiscordRole deletedRole = inServer.Roles.Find(x => x.ID == message["d"]["role_id"].ToString()); + + try + { + ServersList.Find(x => x.ID == inServer.ID).Roles.Remove(ServersList.Find(x => x.ID == inServer.ID).Roles.Find(y => y.ID == deletedRole.ID)); + } + catch (Exception ex) + { + DebugLogger.Log($"Couldn't delete role with ID {message["d"]["role_id"].ToString()}! ({ex.Message})", MessageLevel.Critical); + } + + RoleDeleted?.Invoke(this, new DiscordGuildRoleDeleteEventArgs { DeletedRole = deletedRole, Guild = inServer, RawJson = message }); + } + + /// + /// Creates a default role in the specified guild. + /// + /// The guild to make the role in. + /// The newly created role. + public DiscordRole CreateRole(DiscordServer guild) + { + string url = Endpoints.BaseAPI + Endpoints.Guilds + $"/{guild.ID}" + Endpoints.Roles; + + try + { + var result = JObject.Parse(WebWrapper.Post(url, token, "")); + + if (result != null) + { + DiscordRole d = new DiscordRole + { + Color = new Color(result["color"].ToObject().ToString("x")), + Hoist = result["hoist"].ToObject(), + ID = result["id"].ToString(), + Managed = result["managed"].ToObject(), + Name = result["name"].ToString(), + Permissions = new DiscordPermission(result["permissions"].ToObject()), + Position = result["position"].ToObject() + }; + + ServersList.Find(x => x.ID == guild.ID).Roles.Add(d); + return d; + } + } + catch (Exception ex) + { + DebugLogger.Log($"Error ocurred while creating role in guild {guild.Name}: {ex.Message}", MessageLevel.Error); + } + return null; + } + + /// + /// Edits a role with the new role information. + /// + /// The guild the role is in. + /// the new role. + /// The newly edited role returned from Discord. + public DiscordRole EditRole(DiscordServer guild, DiscordRole newRole) + { + string url = Endpoints.BaseAPI + Endpoints.Guilds + $"/{guild.ID}" + Endpoints.Roles + $"/{newRole.ID}"; + string request = JsonConvert.SerializeObject( + new + { + color = decimal.Parse(newRole.Color.ToDecimal().ToString()), + hoist = newRole.Hoist, + name = newRole.Name, + permissions = newRole.Permissions.GetRawPermissions() + } + ); + + try + { + var result = JObject.Parse(WebWrapper.Patch(url, token, request)); + if (result != null) + { + DiscordRole d = new DiscordRole + { + Color = new Color(result["color"].ToObject().ToString("x")), + Hoist = result["hoist"].ToObject(), + ID = result["id"].ToString(), + Managed = result["managed"].ToObject(), + Name = result["name"].ToString(), + Permissions = new DiscordPermission(result["permissions"].ToObject()), + Position = result["position"].ToObject() + }; + + ServersList.Find(x => x.ID == guild.ID).Roles.Remove(d); + ServersList.Find(x => x.ID == guild.ID).Roles.Add(d); + return d; + } + } + catch (Exception ex) + { + DebugLogger.Log($"Error ocurred while editing role ({newRole.Name}): {ex.Message}", MessageLevel.Error); + } + + return null; + } + + /// + /// Deletes a specified role. + /// + /// The guild the role is in. + /// The role to delete. + public void DeleteRole(DiscordServer guild, DiscordRole role) + { + string url = Endpoints.BaseAPI + Endpoints.Guilds + $"/{guild.ID}" + Endpoints.Roles + $"/{role.ID}"; + try + { + WebWrapper.Delete(url, token); + } + catch (Exception ex) + { + DebugLogger.Log($"Error ocurred while deleting role ({role.Name}): {ex.Message}", MessageLevel.Error); + } + } + + private void GuildUpdateEvents(JObject message) + { + DiscordServer oldServer = ServersList.Find(x => x.ID == message["d"]["id"].ToString()); + DiscordServer newServer = oldServer.ShallowCopy(); + + newServer.Name = message["d"]["name"].ToString(); + newServer.ID = message["d"]["id"].ToString(); + newServer.parentclient = this; + newServer.Roles = new List(); + newServer.Region = message["d"]["region"].ToString(); + if (!message["d"]["icon"].IsNullOrEmpty()) + { + newServer.icon = message["d"]["icon"].ToString(); + } + if (!message["d"]["roles"].IsNullOrEmpty()) + { + foreach (var roll in message["d"]["roles"]) + { + DiscordRole t = new DiscordRole + { + Color = new DiscordSharp.Color(roll["color"].ToObject().ToString("x")), + Name = roll["name"].ToString(), + Permissions = new DiscordPermission(roll["permissions"].ToObject()), + Position = roll["position"].ToObject(), + Managed = roll["managed"].ToObject(), + ID = roll["id"].ToString(), + Hoist = roll["hoist"].ToObject() + }; + newServer.Roles.Add(t); + } + } + else + { + newServer.Roles = oldServer.Roles; + } + newServer.Channels = new List(); + if (!message["d"]["channels"].IsNullOrEmpty()) + { + foreach (var u in message["d"]["channels"]) + { + DiscordChannel tempSub = new DiscordChannel(); + tempSub.Client = this; + tempSub.ID = u["id"].ToString(); + tempSub.Name = u["name"].ToString(); + tempSub.Type = u["type"].ToObject(); + + if (!u["topic"].IsNullOrEmpty()) + tempSub.Topic = u["topic"].ToString(); + if (tempSub.Type == ChannelType.Voice && !u["bitrate"].IsNullOrEmpty()) + tempSub.Bitrate = u["bitrate"].ToObject(); + + tempSub.Parent = newServer; + List permissionoverrides = new List(); + foreach (var o in u["permission_overwrites"]) + { + DiscordPermissionOverride dpo = new DiscordPermissionOverride(o["allow"].ToObject(), o["deny"].ToObject()); + dpo.type = o["type"].ToObject(); + dpo.id = o["id"].ToString(); + + permissionoverrides.Add(dpo); + } + tempSub.PermissionOverrides = permissionoverrides; + + newServer.Channels.Add(tempSub); + } + } + else + { + newServer.Channels = oldServer.Channels; + } + if (!message["d"]["members"].IsNullOrEmpty()) + { + foreach (var mm in message["d"]["members"]) + { + DiscordMember member = JsonConvert.DeserializeObject(mm["user"].ToString()); + member.parentclient = this; + member.Parent = newServer; + + JArray rawRoles = JArray.Parse(mm["roles"].ToString()); + if (rawRoles.Count > 0) + { + foreach (var role in rawRoles.Children()) + { + member.Roles.Add(newServer.Roles.Find(x => x.ID == role.Value())); + } + } + else + { + member.Roles.Add(newServer.Roles.Find(x => x.Name == "@everyone")); + } + + newServer.AddMember(member); + } + } + else + { + newServer.Members = oldServer.Members; + } + if (!message["d"]["owner_id"].IsNullOrEmpty()) + { + newServer.Owner = newServer.GetMemberByKey(message["d"]["owner_id"].ToString()); + DebugLogger.Log($"Transferred ownership from user '{oldServer.Owner.Username}' to {newServer.Owner.Username}."); + } + ServersList.Remove(oldServer); + ServersList.Add(newServer); + DiscordServerUpdateEventArgs dsuea = new DiscordServerUpdateEventArgs { NewServer = newServer, OldServer = oldServer }; + GuildUpdated?.Invoke(this, dsuea); + } + + private void ChannelDeleteEvents(JObject message) + { + if (!message["d"]["recipient"].IsNullOrEmpty()) + { + //private channel removed + DiscordPrivateChannelDeleteEventArgs e = new DiscordPrivateChannelDeleteEventArgs(); + e.PrivateChannelDeleted = PrivateChannels.Find(x => x.ID == message["d"]["id"].ToString()); + if (e.PrivateChannelDeleted != null) + { + if (PrivateChannelDeleted != null) + PrivateChannelDeleted(this, e); + PrivateChannels.Remove(e.PrivateChannelDeleted); + } + else + { + DebugLogger.Log("Error in ChannelDeleteEvents: PrivateChannel is null!", MessageLevel.Error); + } + } + else + { + DiscordChannelDeleteEventArgs e = new DiscordChannelDeleteEventArgs { ChannelDeleted = GetChannelByID(message["d"]["id"].ToObject()) }; + DiscordServer server; + server = e.ChannelDeleted.Parent; + server.Channels.Remove(server.Channels.Find(x => x.ID == e.ChannelDeleted.ID)); + + if (ChannelDeleted != null) + ChannelDeleted(this, e); + } + } + + private void ChannelUpdateEvents(JObject message) + { + DiscordChannelUpdateEventArgs e = new DiscordChannelUpdateEventArgs(); + e.RawJson = message; + DiscordChannel oldChannel = ServersList.Find(x => x.Channels.Find(y => y.ID == message["d"]["id"].ToString()) != null).Channels.Find(x => x.ID == message["d"]["id"].ToString()); + e.OldChannel = oldChannel.ShallowCopy(); + DiscordChannel newChannel = oldChannel; + newChannel.Name = message["d"]["name"].ToString(); + if (!message["d"]["topic"].IsNullOrEmpty()) + newChannel.Topic = message["d"]["topic"].ToString(); + else + newChannel.Topic = oldChannel.Topic; + + newChannel.Private = message["d"]["is_private"].ToObject(); + + List permissionoverrides = new List(); + foreach (var o in message["d"]["permission_overwrites"]) + { + DiscordPermissionOverride dpo = new DiscordPermissionOverride(o["allow"].ToObject(), o["deny"].ToObject()); + dpo.type = o["type"].ToObject(); + dpo.id = o["id"].ToString(); + + permissionoverrides.Add(dpo); + } + newChannel.PermissionOverrides = permissionoverrides; + + e.NewChannel = newChannel; + + DiscordServer serverToRemoveFrom = ServersList.Find(x => x.Channels.Find(y => y.ID == newChannel.ID) != null); + newChannel.Parent = serverToRemoveFrom; + int indexOfServer = ServersList.IndexOf(serverToRemoveFrom); + serverToRemoveFrom.Channels.Remove(oldChannel); + serverToRemoveFrom.Channels.Add(newChannel); + + ServersList.RemoveAt(indexOfServer); + ServersList.Insert(indexOfServer, serverToRemoveFrom); + + if (ChannelUpdated != null) + ChannelUpdated(this, e); + } + + private void GuildDeleteEvents(JObject message) + { + DiscordGuildDeleteEventArgs e = new DiscordGuildDeleteEventArgs(); + e.Server = ServersList.Find(x => x.ID == message["d"]["id"].ToString()); + e.RawJson = message; + ServersList.Remove(e.Server); + if (GuildDeleted != null) + GuildDeleted(this, e); + } + + private void GuildCreateEvents(JObject message) + { + DiscordGuildCreateEventArgs e = new DiscordGuildCreateEventArgs(); + e.RawJson = message; + DiscordServer server = new DiscordServer(); + server.JoinedAt = message["d"]["joined_at"].ToObject(); + server.parentclient = this; + server.ID = message["d"]["id"].ToString(); + server.Name = message["d"]["name"].ToString(); + server.Members = new Dictionary(); + server.Channels = new List(); + server.Roles = new List(); + foreach (var roll in message["d"]["roles"]) + { + DiscordRole t = new DiscordRole + { + Color = new DiscordSharp.Color(roll["color"].ToObject().ToString("x")), + Name = roll["name"].ToString(), + Permissions = new DiscordPermission(roll["permissions"].ToObject()), + Position = roll["position"].ToObject(), + Managed = roll["managed"].ToObject(), + ID = roll["id"].ToString(), + Hoist = roll["hoist"].ToObject() + }; + server.Roles.Add(t); + } + foreach (var chn in message["d"]["channels"]) + { + DiscordChannel tempChannel = new DiscordChannel(); + tempChannel.Client = this; + tempChannel.ID = chn["id"].ToString(); + tempChannel.Type = chn["type"].ToObject(); + + if (!chn["topic"].IsNullOrEmpty()) + tempChannel.Topic = chn["topic"].ToString(); + if (tempChannel.Type == ChannelType.Voice && !chn["bitrate"].IsNullOrEmpty()) + tempChannel.Bitrate = chn["bitrate"].ToObject(); + + tempChannel.Name = chn["name"].ToString(); + tempChannel.Private = false; + tempChannel.PermissionOverrides = new List(); + tempChannel.Parent = server; + foreach (var o in chn["permission_overwrites"]) + { + if (tempChannel.Type == ChannelType.Voice) + continue; + DiscordPermissionOverride dpo = new DiscordPermissionOverride(o["allow"].ToObject(), o["deny"].ToObject()); + dpo.id = o["id"].ToString(); + + if (o["type"].ToString() == "member") + dpo.type = DiscordPermissionOverride.OverrideType.member; + else + dpo.type = DiscordPermissionOverride.OverrideType.role; + + tempChannel.PermissionOverrides.Add(dpo); + } + server.Channels.Add(tempChannel); + } + foreach (var mbr in message["d"]["members"]) + { + DiscordMember member = JsonConvert.DeserializeObject(mbr["user"].ToString()); + if (mbr["nick"] != null) + member.Nickname = mbr["nick"].ToString(); + + member.parentclient = this; + member.Parent = server; + + foreach (var rollid in mbr["roles"]) + { + member.Roles.Add(server.Roles.Find(x => x.ID == rollid.ToString())); + } + if (member.Roles.Count == 0) + member.Roles.Add(server.Roles.Find(x => x.Name == "@everyone")); + server.AddMember(member); + } + foreach (var voiceStateJSON in message["d"]["voice_states"]) + { + DiscordVoiceState voiceState = JsonConvert.DeserializeObject(voiceStateJSON.ToString()); + DiscordMember member = server.GetMemberByKey(voiceState.UserID); + + member.CurrentVoiceChannel = server.Channels.Find(x => x.ID == voiceState.ChannelID); + member.VoiceState = voiceState; + } + server.Owner = server.GetMemberByKey(message["d"]["owner_id"].ToString()); + e.Server = server; + + if (!message["d"]["unavailable"].IsNullOrEmpty() && message["d"]["unavailable"].ToObject() == false) + { + var oldServer = ServersList.Find(x => x.ID == server.ID); + if (oldServer != null && oldServer.Unavailable) + ServersList.Remove(oldServer); + + ServersList.Add(server); + + DebugLogger.Log($"Guild with ID {server.ID} ({server.Name}) became available."); + GuildAvailable?.Invoke(this, e); + return; + } + + ServersList.Add(server); + GuildCreated?.Invoke(this, e); + } + + private void GuildMemberAddEvents(JObject message) + { + DiscordGuildMemberAddEventArgs e = new DiscordGuildMemberAddEventArgs(); + e.RawJson = message; + e.Guild = ServersList.Find(x => x.ID == message["d"]["guild_id"].ToString()); + + DiscordMember existingMember = e.Guild.GetMemberByKey(message["d"]["user"]["id"].ToString()); + if (existingMember != null) + { + + DiscordMember newMember = JsonConvert.DeserializeObject(message["d"]["user"].ToString()); + newMember.parentclient = this; + e.AddedMember = newMember; + newMember.Parent = e.Guild; + e.Roles = message["d"]["roles"].ToObject(); + e.JoinedAt = DateTime.Parse(message["d"]["joined_at"].ToString()); + + ServersList.Find(x => x == e.Guild).AddMember(newMember); + if (UserAddedToServer != null) + UserAddedToServer(this, e); + } + else + { + DebugLogger.Log($"Skipping guild member add because user already exists in server.", MessageLevel.Debug); + } + } + private void GuildMemberRemoveEvents(JObject message) + { + DiscordGuildMemberRemovedEventArgs e = new DiscordGuildMemberRemovedEventArgs(); + DiscordMember removed = new DiscordMember(this); + removed.parentclient = this; + + List membersToRemove = new List(); + foreach (var server in ServersList) + { + if (server.ID != message["d"]["guild_id"].ToString()) + continue; + foreach (var member in server.Members) + { + if (member.Value.ID == message["d"]["user"]["id"].ToString()) + { + removed = member.Value; + membersToRemove.Add(removed); + RemovedMembers.Add(removed); + } + } + } + + foreach (var member in membersToRemove) + { + foreach (var server in ServersList) + { + try + { + server.RemoveMember(member.ID); + } + catch { } //oh, you mean useless? + } + } + e.MemberRemoved = removed; + e.Server = ServersList.Find(x => x.ID == message["d"]["guild_id"].ToString()); + e.RawJson = message; + + if (UserRemovedFromServer != null) + UserRemovedFromServer(this, e); + } + + private void UserUpdateEvents(JObject message) + { + DiscordUserUpdateEventArgs e = new DiscordUserUpdateEventArgs(); + e.RawJson = message; + DiscordMember newMember = JsonConvert.DeserializeObject(message["d"].ToString()); + newMember.parentclient = this; + + DiscordMember oldMember = new DiscordMember(this); + oldMember.parentclient = this; + //Update members + foreach (var server in ServersList) + { + + foreach (var member in server.Members) + { + if (member.Value.ID == newMember.ID) + { + oldMember = member.Value; + server.AddMember(newMember); + break; + } + } + } + + newMember.Parent = oldMember.Parent; + + if (!message["roles"].IsNullOrEmpty()) + { + JArray rawRoles = JArray.Parse(message["roles"].ToString()); + if (rawRoles.Count > 0) + { + foreach (var role in rawRoles.Children()) + { + newMember.Roles.Add(newMember.Parent.Roles.Find(x => x.ID == role.ToString())); + } + } + else + { + newMember.Roles.Add(newMember.Parent.Roles.Find(x => x.Name == "@everyone")); + } + } + + e.NewMember = newMember; + e.OriginalMember = oldMember; + UserUpdate?.Invoke(this, e); + } + + private void MessageDeletedEvents(JObject message) + { + DiscordMessageDeletedEventArgs e = new DiscordMessageDeletedEventArgs(); + e.DeletedMessage = FindInMessageLog(message["d"]["id"].ToString()); + + DiscordServer inServer; + inServer = ServersList.Find(x => x.Channels.Find(y => y.ID == message["d"]["channel_id"].ToString()) != null); + if (inServer == null) //dm delete + { + DiscordPrivateMessageDeletedEventArgs dm = new DiscordPrivateMessageDeletedEventArgs(); + dm.DeletedMessage = e.DeletedMessage; + dm.RawJson = message; + dm.Channel = PrivateChannels.Find(x => x.ID == message["d"]["channel_id"].ToString()); + if (PrivateMessageDeleted != null) + PrivateMessageDeleted(this, dm); + } + else + { + e.Channel = inServer.Channels.Find(x => x.ID == message["d"]["channel_id"].ToString()); + e.RawJson = message; + } + + if (MessageDeleted != null) + MessageDeleted(this, e); + } + + private void VoiceStateUpdateEvents(JObject message) + { + var f = message["d"]["channel_id"]; + if (f.ToString() == null) + { + DiscordLeftVoiceChannelEventArgs le = new DiscordLeftVoiceChannelEventArgs(); + DiscordServer inServer = ServersList.Find(x => x.ID == message["d"]["guild_id"].ToString()); + le.User = inServer.GetMemberByKey(message["d"]["user_id"].ToString()); + le.Guild = inServer; + le.RawJson = message; + + if (VoiceClient != null && VoiceClient.Connected) + VoiceClient.MemberRemoved(le.User); + if (UserLeftVoiceChannel != null) + UserLeftVoiceChannel(this, le); + return; + } + DiscordVoiceStateUpdateEventArgs e = new DiscordVoiceStateUpdateEventArgs(); + e.Guild = ServersList.Find(x => x.ID == message["d"]["guild_id"].ToString()); + DiscordMember memberToUpdate = e.Guild.GetMemberByKey(message["d"]["user_id"].ToString()); + if (memberToUpdate != null) + { + e.Channel = e.Guild.Channels.Find(x => x.ID == message["d"]["channel_id"].ToString()); + memberToUpdate.CurrentVoiceChannel = e.Channel; + if (!message["d"]["self_deaf"].IsNullOrEmpty()) + e.SelfDeaf = message["d"]["self_deaf"].ToObject(); + e.Deaf = message["d"]["deaf"].ToObject(); + if (!message["d"]["self_mute"].IsNullOrEmpty()) + e.SelfMute = message["d"]["self_mute"].ToObject(); + e.Mute = message["d"]["mute"].ToObject(); + memberToUpdate.Muted = e.Mute; + e.Suppress = message["d"]["suppress"].ToObject(); + memberToUpdate.Deaf = e.Suppress; + e.RawJson = message; + + e.User = memberToUpdate; + + if (VoiceClient != null && VoiceClient.Connected) + VoiceClient.MemberAdded(e.User); + + if (!message["d"]["session_id"].IsNullOrEmpty()) //then this has to do with you + { + if (e.User.ID == Me.ID) + { + Me.Muted = e.SelfMute; + Me.Deaf = e.SelfDeaf; + if (VoiceClient != null) + VoiceClient.SessionID = message["d"]["session_id"].ToString(); + } + } + + if (VoiceStateUpdate != null) + VoiceStateUpdate(this, e); + } + } + private JObject ServerInfo(string channelOrServerId) + { + string url = Endpoints.BaseAPI + Endpoints.Guilds + $"/{channelOrServerId}"; + try + { + return JObject.Parse(WebWrapper.Get(url, token)); + } + catch (Exception ex) + { + DebugLogger.Log("(Private) Error ocurred while retrieving server info: " + ex.Message, MessageLevel.Error); + } + return null; + } + + private int HeartbeatInterval = 41250; + private static DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + private async void KeepAlive() + { + //string keepAliveJson = "{\"op\":" + Opcodes.HEARTBEAT + ", \"d\":" + Sequence + "}"; + string keepAliveJson = JsonConvert.SerializeObject(new + { + op = Opcodes.HEARTBEAT, + d = Sequence + }); + if (ws != null) + { + await ws.SendMessage(keepAliveJson); + KeepAliveSent?.Invoke(this, new DiscordKeepAliveSentEventArgs { SentAt = DateTime.Now, JsonSent = keepAliveJson }); + } + } + + /// + /// Disposes. + /// + public void Dispose() + { + try + { + KeepAliveTaskTokenSource.Cancel(); + ws.Close(); + ws = null; + ServersList = null; + PrivateChannels = null; + Me = null; + token = null; + this.ClientPrivateInformation = null; + } + catch { /*already been disposed elsewhere */ } + } + + /// + /// Logs out of Discord and then disposes. + /// + public void Logout() + { + string url = Endpoints.BaseAPI + Endpoints.Auth + "/logout"; + string msg = JsonConvert.SerializeObject(new { token = token }); + WebWrapper.Post(url, msg); + Dispose(); + } + + /// + /// Sends a login request. + /// + /// The token if login was succesful, or null if not + public string SendLoginRequest() + { + if (token == null) //no token override provided, need to read token + { + if (String.IsNullOrEmpty(ClientPrivateInformation.Email)) + { + throw new ArgumentNullException("Email was null/invalid!"); + } + StrippedEmail = ClientPrivateInformation.Email.Replace('@', '_').Replace('.', '_'); //strips characters from email for hashing + + if (File.Exists(StrippedEmail.GetHashCode() + ".cache")) + { + string read = ""; + using (var sr = new StreamReader(StrippedEmail.GetHashCode() + ".cache")) + { + read = sr.ReadLine(); + if (read.StartsWith("#")) //comment + { + token = sr.ReadLine(); + DebugLogger.Log("Loading token from cache."); + } + token = token.Trim(); //trim any excess whitespace + } + } + else + { + if (ClientPrivateInformation == null || ClientPrivateInformation.Email == null || ClientPrivateInformation.Password == null) + throw new ArgumentNullException("You didn't supply login information!"); + string url = Endpoints.BaseAPI + Endpoints.Auth + Endpoints.Login; + string msg = JsonConvert.SerializeObject(new + { + email = ClientPrivateInformation.Email, + password = ClientPrivateInformation.Password + }); + DebugLogger.Log("No token present, sending login request.."); + var result = JObject.Parse(WebWrapper.Post(url, msg)); + + if (result["token"].IsNullOrEmpty()) + { + string message = "Failed to login to Discord."; + if (!result["email"].IsNullOrEmpty()) + message += " Email was invalid: " + result["email"]; + if (!result["password"].IsNullOrEmpty()) + message += " password was invalid: " + result["password"]; + if (!result["captcha_key"].IsNullOrEmpty()) + message += " captcha required for this IP address: " + result["captcha_key"].ToString(); + + throw new DiscordLoginException(message); + } + token = result["token"].ToString(); + + using (var sw = new StreamWriter(StrippedEmail.GetHashCode() + ".cache")) + { + sw.WriteLine($"#Token cache for {ClientPrivateInformation.Email}"); + sw.WriteLine(token); + DebugLogger.Log($"{StrippedEmail.GetHashCode()}.cache written!"); + } + } + } + return token; + } + } +} diff --git a/DiscordSharp/DiscordSharp.csproj b/.NET framework/DiscordSharp/DiscordSharp.csproj similarity index 94% rename from DiscordSharp/DiscordSharp.csproj rename to .NET framework/DiscordSharp/DiscordSharp.csproj index 03d32f6..0291ca1 100644 --- a/DiscordSharp/DiscordSharp.csproj +++ b/.NET framework/DiscordSharp/DiscordSharp.csproj @@ -1,5 +1,5 @@  - + Debug @@ -12,12 +12,12 @@ 512 False - v4.5 + v4.6.1 true full - false + true bin\Debug\ - - - wrapper class to box the initialized value, this is mainly created to avoid boxing/unboxing the value each time the value is called in case T is - a value type - - - - - Wrapper class to wrap the excpetion thrown by the value factory - - - - A debugger view of the Lazy<T> to surface additional debugging properties and - to ensure that the Lazy<T> does not become initialized if it was not already. - - - Constructs a new debugger view object for the provided Lazy object. - A Lazy object to browse in the debugger. - - - Returns whether the Lazy object is initialized or not. - - - Returns the value of the Lazy object. - - - Returns the execution mode of the Lazy object - - - Returns the execution mode of the Lazy object - - - - Specifies how a instance should synchronize access among multiple threads. - - - - - This mode makes no guarantees around the thread-safety of the instance. If used from multiple threads, the behavior of the is undefined. - This mode should be used when a is guaranteed to never be initialized from more than one thread simultaneously and high performance is crucial. - If valueFactory throws an exception when the is initialized, the exception will be cached and returned on subsequent accesses to Value. Also, if valueFactory recursively - accesses Value on this instance, a will be thrown. - - - - - When multiple threads attempt to simultaneously initialize a instance, this mode allows each thread to execute the - valueFactory but only the first thread to complete initialization will be allowed to set the final value of the . - Once initialized successfully, any future calls to Value will return the cached result. If valueFactory throws an exception on any thread, that exception will be - propagated out of Value. If any thread executes valueFactory without throwing an exception and, therefore, successfully sets the value, that value will be returned on - subsequent accesses to Value from any thread. If no thread succeeds in setting the value, IsValueCreated will remain false and subsequent accesses to Value will result in - the valueFactory delegate re-executing. Also, if valueFactory recursively accesses Value on this instance, an exception will NOT be thrown. - - - - - This mode uses locks to ensure that only a single thread can initialize a instance in a thread-safe manner. In general, - taken if this mode is used in conjunction with a valueFactory delegate that uses locks internally, a deadlock can occur if not - handled carefully. If valueFactory throws an exception when the is initialized, the exception will be cached and returned on - subsequent accesses to Value. Also, if valueFactory recursively accesses Value on this instance, a will be thrown. - - - - - Provides lazy initialization routines. - - - These routines avoid needing to allocate a dedicated, lazy-initialization instance, instead using - references to ensure targets have been initialized as they are accessed. - - - - - Initializes a target reference type with the type's default constructor if the target has not - already been initialized. - - The refence type of the reference to be initialized. - A reference of type to initialize if it has not - already been initialized. - The initialized reference of type . - Type does not have a default - constructor. - - Permissions to access the constructor of type were missing. - - - - This method may only be used on reference types. To ensure initialization of value - types, see other overloads of EnsureInitialized. - - - This method may be used concurrently by multiple threads to initialize . - In the event that multiple threads access this method concurrently, multiple instances of - may be created, but only one will be stored into . In such an occurrence, this method will not dispose of the - objects that were not stored. If such objects must be disposed, it is up to the caller to determine - if an object was not used and to then dispose of the object appropriately. - - - - - - Initializes a target reference type using the specified function if it has not already been - initialized. - - The reference type of the reference to be initialized. - The reference of type to initialize if it has not - already been initialized. - The invoked to initialize the - reference. - The initialized reference of type . - Type does not have a - default constructor. - returned - null. - - - This method may only be used on reference types, and may - not return a null reference (Nothing in Visual Basic). To ensure initialization of value types or - to allow null reference types, see other overloads of EnsureInitialized. - - - This method may be used concurrently by multiple threads to initialize . - In the event that multiple threads access this method concurrently, multiple instances of - may be created, but only one will be stored into . In such an occurrence, this method will not dispose of the - objects that were not stored. If such objects must be disposed, it is up to the caller to determine - if an object was not used and to then dispose of the object appropriately. - - - - - - Initialize the target using the given delegate (slow path). - - The reference type of the reference to be initialized. - The variable that need to be initialized - The delegate that will be executed to initialize the target - The initialized variable - - - - Initializes a target reference or value type with its default constructor if it has not already - been initialized. - - The type of the reference to be initialized. - A reference or value of type to initialize if it - has not already been initialized. - A reference to a boolean that determines whether the target has already - been initialized. - A reference to an object used as the mutually exclusive lock for initializing - . - The initialized value of type . - - - - Initializes a target reference or value type with a specified function if it has not already been - initialized. - - The type of the reference to be initialized. - A reference or value of type to initialize if it - has not already been initialized. - A reference to a boolean that determines whether the target has already - been initialized. - A reference to an object used as the mutually exclusive lock for initializing - . - The invoked to initialize the - reference or value. - The initialized value of type . - - - - Ensure the target is initialized and return the value (slow path). This overload permits nulls - and also works for value type targets. Uses the supplied function to create the value. - - The type of target. - A reference to the target to be initialized. - A reference to a location tracking whether the target has been initialized. - A reference to a location containing a mutual exclusive lock. - - The to invoke in order to produce the lazily-initialized value. - - The initialized object. - - - - A seprate non generic class that contains a global counter for fast path instances for all Ts that has been created, and adds an upper limit for all instances - that uses the fast path, if this limit has been reached, all new instances will use the slow path - - - - - Provides thread-local storage of data. - - Specifies the type of data stored per-thread. - - - With the exception of , all public and protected members of - are thread-safe and may be used - concurrently from multiple threads. - - - - - - Initializes the instance. - - - - - Initializes the instance with the - specified function. - - - The invoked to produce a lazily-initialized value when - an attempt is made to retrieve without it having been previously initialized. - - - is a null reference (Nothing in Visual Basic). - - - - - Releases the resources used by this instance. - - - - - Releases the resources used by this instance. - - - Unlike most of the members of , this method is not thread-safe. - - - - - Releases the resources used by this instance. - - - A Boolean value that indicates whether this method is being called due to a call to . - - - Unlike most of the members of , this method is not thread-safe. - - - - - Tries to get a unique index for the current instance of type T, it first tries to get it from the pool if it is not empty, otherwise it - increments the global counter if it is still below the maximum, otherwise it fails and returns -1 - - True if there is an index available, false otherwise - - - - Gets an array of types that will be used as generic parameters for the GenericHolder class - - The types array - - - Creates and returns a string representation of this instance for the current thread. - The result of calling on the . - - The for the current thread is a null reference (Nothing in Visual Basic). - - - The initialization function referenced in an improper manner. - - - The instance has been disposed. - - - Calling this method forces initialization for the current thread, as is the - case with accessing directly. - - - - - Private helper function to lazily create the value using the calueSelector if specified in the constructor or the default parameterless constructor - - Returns the boxed object - - - - Gets or sets the value of this instance for the current thread. - - - The initialization function referenced in an improper manner. - - - The instance has been disposed. - - - If this instance was not previously initialized for the current thread, - accessing will attempt to initialize it. If an initialization function was - supplied during the construction, that initialization will happen by invoking the function - to retrieve the initial value for . Otherwise, the default value of - will be used. - - - - - Gets whether is initialized on the current thread. - - - The instance has been disposed. - - - - Gets the value of the ThreadLocal<T> for debugging display purposes. It takes care of getting - the value for the current thread in the ThreadLocal mode. - - - - The base abstract class for the holder - - - - - The TLS holder representation - - - - - The generic holder representation - - Dummy param - Dummy param - Dummy param - - - - wrapper to the actual value - - - - A debugger view of the ThreadLocal<T> to surface additional debugging properties and - to ensure that the ThreadLocal<T> does not become initialized if it was not already. - - - Constructs a new debugger view object for the provided ThreadLocal object. - A ThreadLocal object to browse in the debugger. - - - Returns whether the ThreadLocal object is initialized or not. - - - Returns the value of the ThreadLocal object. - - - - Limits the number of threads that can access a resource or pool of resources concurrently. - - - - The provides a lightweight semaphore class that doesn't - use Windows kernel semaphores. - - - All public and protected members of are thread-safe and may be used - concurrently from multiple threads, with the exception of Dispose, which - must only be used when all other operations on the have - completed. - - - - - - Initializes a new instance of the class, specifying - the initial number of requests that can be granted concurrently. - - The initial number of requests for the semaphore that can be granted - concurrently. - - is less than 0. - - - - Initializes a new instance of the class, specifying - the initial and maximum number of requests that can be granted concurrently. - - The initial number of requests for the semaphore that can be granted - concurrently. - The maximum number of requests for the semaphore that can be granted - concurrently. - - is less than 0. -or- - is greater than . -or- - is less than 0. - - - - Blocks the current thread until it can enter the . - - The current instance has already been - disposed. - - - - Blocks the current thread until it can enter the , while observing a - . - - The token to - observe. - was - canceled. - The current instance has already been - disposed. - - - - Blocks the current thread until it can enter the , using a to measure the time interval. - - A that represents the number of milliseconds - to wait, or a that represents -1 milliseconds to wait indefinitely. - - true if the current thread successfully entered the ; - otherwise, false. - is a negative - number other than -1 milliseconds, which represents an infinite time-out -or- timeout is greater - than . - - - - Blocks the current thread until it can enter the , using a to measure the time interval, while observing a . - - A that represents the number of milliseconds - to wait, or a that represents -1 milliseconds to wait indefinitely. - - The to - observe. - true if the current thread successfully entered the ; - otherwise, false. - is a negative - number other than -1 milliseconds, which represents an infinite time-out -or- timeout is greater - than . - was canceled. - - - - Blocks the current thread until it can enter the , using a 32-bit - signed integer to measure the time interval. - - The number of milliseconds to wait, or (-1) to wait indefinitely. - true if the current thread successfully entered the ; - otherwise, false. - is a - negative number other than -1, which represents an infinite time-out. - - - - Blocks the current thread until it can enter the , - using a 32-bit signed integer to measure the time interval, - while observing a . - - The number of milliseconds to wait, or (-1) to - wait indefinitely. - The to observe. - true if the current thread successfully entered the ; otherwise, false. - is a negative number other than -1, - which represents an infinite time-out. - was canceled. - - - - Local helper function, waits on the monitor until the monitor recieves signal or the - timeout is expired - - The maximum timeout - The start ticks to calculate the elapsed time - The CancellationToken to observe. - true if the monitor recieved a signal, false if the timeout expired - - - - Exits the once. - - The previous count of the . - The current instance has already been - disposed. - - - - Exits the a specified number of times. - - The number of times to exit the semaphore. - The previous count of the . - is less - than 1. - The has - already reached its maximum size. - The current instance has already been - disposed. - - - - Releases all resources used by the current instance of . - - - Unlike most of the members of , is not - thread-safe and may not be used concurrently with other members of this instance. - - - - - When overridden in a derived class, releases the unmanaged resources used by the - , and optionally releases the managed resources. - - true to release both managed and unmanaged resources; - false to release only unmanaged resources. - - Unlike most of the members of , is not - thread-safe and may not be used concurrently with other members of this instance. - - - - - Helper function to measure and update the wait time - - The first time (in Ticks) observed when the wait started - The orginal wait timeoutout in milliseconds - The new wait time in milliseconds, -1 if the time expired - - - - Private helper method to wake up waiters when a cancellationToken gets canceled. - - - - - Checks the dispose status by checking the lock object, if it is null means that object - has been disposed and throw ObjectDisposedException - - - - - local helper function to retrieve the exception string message from the resource file - - The key string - - - - Gets the current count of the . - - The current count of the . - - - - Returns a that can be used to wait on the semaphore. - - A that can be used to wait on the - semaphore. - - A successful wait on the does not imply a successful wait on - the itself, nor does it decrement the semaphore's - count. exists to allow a thread to block waiting on multiple - semaphores, but such a wait should be followed by a true wait on the target semaphore. - - The has been disposed. - - - - Provides support for spin-based waiting. - - - - encapsulates common spinning logic. On single-processor machines, yields are - always used instead of busy waits, and on computers with Intel™ processors employing Hyper-Threading™ - technology, it helps to prevent hardware thread starvation. SpinWait encapsulates a good mixture of - spinning and true yielding. - - - is a value type, which means that low-level code can utilize SpinWait without - fear of unnecessary allocation overheads. SpinWait is not generally useful for ordinary applications. - In most cases, you should use the synchronization classes provided by the .NET Framework, such as - . For most purposes where spin waiting is required, however, - the type should be preferred over the method. - - - While SpinWait is designed to be used in concurrent applications, it is not designed to be - used from multiple threads concurrently. SpinWait's members are not thread-safe. If multiple - threads must spin, each should use its own instance of SpinWait. - - - - - - Performs a single spin. - - - This is typically called in a loop, and may change in behavior based on the number of times a - has been called thus far on this instance. - - - - - Resets the spin counter. - - - This makes and behave as though no calls - to had been issued on this instance. If a instance - is reused many times, it may be useful to reset it to avoid yielding too soon. - - - - - Spins until the specified condition is satisfied. - - A delegate to be executed over and over until it returns true. - The argument is null. - - - - Spins until the specified condition is satisfied or until the specified timeout is expired. - - A delegate to be executed over and over until it returns true. - - A that represents the number of milliseconds to wait, - or a TimeSpan that represents -1 milliseconds to wait indefinitely. - True if the condition is satisfied within the timeout; otherwise, false - The argument is null. - is a negative number - other than -1 milliseconds, which represents an infinite time-out -or- timeout is greater than - . - - - - Spins until the specified condition is satisfied or until the specified timeout is expired. - - A delegate to be executed over and over until it returns true. - The number of milliseconds to wait, or (-1) to wait indefinitely. - True if the condition is satisfied within the timeout; otherwise, false - The argument is null. - is a - negative number other than -1, which represents an infinite time-out. - - - - Gets the number of times has been called on this instance. - - - - - Gets whether the next call to will yield the processor, triggering a - forced context switch. - - Whether the next call to will yield the processor, triggering a - forced context switch. - - On a single-CPU machine, always yields the processor. On machines with - multiple CPUs, may yield after an unspecified number of calls. - - - - - A helper class to get the number of preocessors, it updates the numbers of processors every sampling interval - - - - - Gets the number of available processors - - - - - Gets whether the current machine has only a single processor. - - - - - Provides a mutual exclusion lock primitive where a thread trying to acquire the lock waits in a loop - repeatedly checking until the lock becomes available. - - - - Spin locks can be used for leaf-level locks where the object allocation implied by using a , in size or due to garbage collection pressure, is overly - expensive. Avoiding blocking is another reason that a spin lock can be useful, however if you expect - any significant amount of blocking, you are probably best not using spin locks due to excessive - spinning. Spinning can be beneficial when locks are fine grained and large in number (for example, a - lock per node in a linked list) as well as when lock hold times are always extremely short. In - general, while holding a spin lock, one should avoid blocking, calling anything that itself may - block, holding more than one spin lock at once, making dynamically dispatched calls (interface and - virtuals), making statically dispatched calls into any code one doesn't own, or allocating memory. - - - should only be used when it's been determined that doing so will improve an - application's performance. It's also important to note that is a value type, - for performance reasons. As such, one must be very careful not to accidentally copy a SpinLock - instance, as the two instances (the original and the copy) would then be completely independent of - one another, which would likely lead to erroneous behavior of the application. If a SpinLock instance - must be passed around, it should be passed by reference rather than by value. - - - Do not store instances in readonly fields. - - - All members of are thread-safe and may be used from multiple threads - concurrently. - - - - - - Initializes a new instance of the - structure with the option to track thread IDs to improve debugging. - - - The default constructor for tracks thread ownership. - - Whether to capture and use thread IDs for debugging - purposes. - - - - Initializes a new instance of the - structure with the option to track thread IDs to improve debugging. - - - The default constructor for tracks thread ownership. - - - Acquires the lock in a reliable manner, such that even if an exception occurs within the method - call, can be examined reliably to determine whether the lock was - acquired. - - - is a non-reentrant lock, meaning that if a thread holds the lock, it is - not allowed to enter the lock again. If thread ownership tracking is enabled (whether it's - enabled is available through ), an exception will be - thrown when a thread tries to re-enter a lock it already holds. However, if thread ownership - tracking is disabled, attempting to enter a lock already held will result in deadlock. - - True if the lock is acquired; otherwise, false. must be initialized to false prior to calling this method. - - Thread ownership tracking is enabled, and the current thread has already acquired this lock. - - - The argument must be initialized to false prior to calling Enter. - - - - - Attempts to acquire the lock in a reliable manner, such that even if an exception occurs within - the method call, can be examined reliably to determine whether the - lock was acquired. - - - Unlike , TryEnter will not block waiting for the lock to be available. If the - lock is not available when TryEnter is called, it will return immediately without any further - spinning. - - True if the lock is acquired; otherwise, false. must be initialized to false prior to calling this method. - - Thread ownership tracking is enabled, and the current thread has already acquired this lock. - - - The argument must be initialized to false prior to calling TryEnter. - - - - - Attempts to acquire the lock in a reliable manner, such that even if an exception occurs within - the method call, can be examined reliably to determine whether the - lock was acquired. - - - Unlike , TryEnter will not block indefinitely waiting for the lock to be - available. It will block until either the lock is available or until the - has expired. - - A that represents the number of milliseconds - to wait, or a that represents -1 milliseconds to wait indefinitely. - - True if the lock is acquired; otherwise, false. must be initialized to false prior to calling this method. - - Thread ownership tracking is enabled, and the current thread has already acquired this lock. - - - The argument must be initialized to false prior to calling TryEnter. - - is a negative - number other than -1 milliseconds, which represents an infinite time-out -or- timeout is greater - than milliseconds. - - - - - Attempts to acquire the lock in a reliable manner, such that even if an exception occurs within - the method call, can be examined reliably to determine whether the - lock was acquired. - - - Unlike , TryEnter will not block indefinitely waiting for the lock to be - available. It will block until either the lock is available or until the has expired. - - The number of milliseconds to wait, or (-1) to wait indefinitely. - True if the lock is acquired; otherwise, false. must be initialized to false prior to calling this method. - - Thread ownership tracking is enabled, and the current thread has already acquired this lock. - - - The argument must be initialized to false prior to calling TryEnter. - - is - a negative number other than -1, which represents an infinite time-out. - - - - Try acquire the lock with long path, this is usually called after the first path in Enter and - TryEnter failed The reason for short path is to make it inline in the run time which improves the - performance. This method assumed that the parameter are validated in Enter ir TryENter method - - The timeout milliseconds - The lockTaken param - - - - decrements the waiters, in case of the timeout is expired - - - - - ContinueTryEnter for the thread tracking mode enabled - - - - - Helper function to validate the timeout - - The start time in ticks - The orginal wait time - True if expired, false otherwise - - - - Releases the lock. - - - The default overload of provides the same behavior as if calling using true as the argument. - - - Thread ownership tracking is enabled, and the current thread is not the owner of this lock. - - - - - Releases the lock. - - - A Boolean value that indicates whether a memory fence should be issued in order to immediately - publish the exit operation to other threads. - - - Calling with the argument set to - true will improve the fairness of the lock at the expense of some performance. The default - overload behaves as if specifying true for . - - - Thread ownership tracking is enabled, and the current thread is not the owner of this lock. - - - - - Gets whether the lock is currently held by any thread. - - - - - Gets whether the lock is currently held by any thread. - - - Gets whether the lock is held by the current thread. - - - If the lock was initialized to track owner threads, this will return whether the lock is acquired - by the current thread. It is invalid to use this property when the lock was initialized to not - track thread ownership. - - - Thread ownership tracking is disabled. - - - - Gets whether thread ownership tracking is enabled for this instance. - - - - Internal class used by debug type proxy attribute to display the owner thread ID - - - - - SystemThreading_SpinLockDebugView constructor - - The SpinLock to be proxied. - - - - Checks if the lock is held by the current thread or not - - - - - Gets the current owner thread, zero if it is released - - - - - Gets whether the lock is currently held by any thread or not. - - - - - Stores options that configure the operation of methods on the - Parallel class. - - - By default, methods on the Parallel class attempt to utilize all available processors, are non-cancelable, and target - the default TaskScheduler (TaskScheduler.Default). enables - overriding these defaults. - - - - - Initializes a new instance of the class. - - - This constructor initializes the instance with default values. - is initialized to -1, signifying that there is no upper bound set on how much parallelism should - be employed. is initialized to a non-cancelable token, - and is initialized to the default scheduler (TaskScheduler.Default). - All of these defaults may be overwritten using the property set accessors on the instance. - - - - - Gets or sets the TaskScheduler - associated with this instance. Setting this property to null - indicates that the current scheduler should be used. - - - - - Gets or sets the maximum degree of parallelism enabled by this ParallelOptions instance. - - - The limits the number of concurrent operations run by Parallel method calls that are passed this - ParallelOptions instance to the set value, if it is positive. If is -1, then there is no limit placed on the number of concurrently - running operations. - - - The exception that is thrown when this is set to 0 or some - value less than -1. - - - - - Gets or sets the CancellationToken - associated with this instance. - - - Providing a CancellationToken - to a Parallel method enables the operation to be - exited early. Code external to the operation may cancel the token, and if the operation observes the - token being set, it may exit early by throwing an - . - - - - - Provides support for parallel loops and regions. - - - The class provides library-based data parallel replacements - for common operations such as for loops, for each loops, and execution of a set of statements. - - - - - Executes each of the provided actions, possibly in parallel. - - An array of Actions to execute. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null element. - The exception that is thrown when any - action in the array throws an exception. - - This method can be used to execute a set of operations, potentially in parallel. - No guarantees are made about the order in which the operations execute or whether - they execute in parallel. This method does not return until each of the - provided operations has completed, regardless of whether completion - occurs due to normal or exceptional termination. - - - - - Executes each of the provided actions, possibly in parallel. - - A ParallelOptions - instance that configures the behavior of this operation. - An array of Actions to execute. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null element. - The exception that is thrown when - the CancellationToken in the - is set. - The exception that is thrown when any - action in the array throws an exception. - The exception that is thrown when the - the CancellationTokenSource associated with the - the CancellationToken in the - has been disposed. - - This method can be used to execute a set of operations, potentially in parallel. - No guarantees are made about the order in which the operations execute or whether - the they execute in parallel. This method does not return until each of the - provided operations has completed, regardless of whether completion - occurs due to normal or exceptional termination. - - - - - Executes a for loop in which iterations may run in parallel. - - The start index, inclusive. - The end index, exclusive. - The delegate that is invoked once per iteration. - The exception that is thrown when the - argument is null. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - The delegate is invoked once for each value in the iteration range: - [fromInclusive, toExclusive). It is provided with the iteration count (an Int32) as a parameter. - - - - - Executes a for loop in which iterations may run in parallel. - - The start index, inclusive. - The end index, exclusive. - The delegate that is invoked once per iteration. - The exception that is thrown when the - argument is null. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - The delegate is invoked once for each value in the iteration range: - [fromInclusive, toExclusive). It is provided with the iteration count (an Int64) as a parameter. - - - - - Executes a for loop in which iterations may run in parallel. - - The start index, inclusive. - The end index, exclusive. - A ParallelOptions - instance that configures the behavior of this operation. - The delegate that is invoked once per iteration. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - CancellationToken in the - argument is set. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - The exception that is thrown when the - the CancellationTokenSource associated with the - the CancellationToken in the - has been disposed. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - The delegate is invoked once for each value in the iteration range: - [fromInclusive, toExclusive). It is provided with the iteration count (an Int32) as a parameter. - - - - - Executes a for loop in which iterations may run in parallel. - - The start index, inclusive. - The end index, exclusive. - A ParallelOptions - instance that configures the behavior of this operation. - The delegate that is invoked once per iteration. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - CancellationToken in the - argument is set. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - The exception that is thrown when the - the CancellationTokenSource associated with the - the CancellationToken in the - has been disposed. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - The delegate is invoked once for each value in the iteration range: - [fromInclusive, toExclusive). It is provided with the iteration count (an Int64) as a parameter. - - - - - Executes a for loop in which iterations may run in parallel. - - The start index, inclusive. - The end index, exclusive. - The delegate that is invoked once per iteration. - The exception that is thrown when the - argument is null. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - - The delegate is invoked once for each value in the iteration range: - [fromInclusive, toExclusive). It is provided with the following parameters: the iteration count (an Int32), - and a ParallelLoopState instance that may be - used to break out of the loop prematurely. - - - Calling ParallelLoopState.Break() - informs the For operation that iterations after the current one need not - execute. However, all iterations before the current one will still need to be executed if they have not already. - Therefore, calling Break is similar to using a break operation within a - conventional for loop in a language like C#, but it is not a perfect substitute: for example, there is no guarantee that iterations - after the current one will definitely not execute. - - - If executing all iterations before the current one is not necessary, - ParallelLoopState.Stop() - should be preferred to using Break. Calling Stop informs the For loop that it may abandon all remaining - iterations, regardless of whether they're for interations above or below the current, - since all required work has already been completed. As with Break, however, there are no guarantees regarding - which other iterations will not execute. - - - When a loop is ended prematurely, the that's returned will contain - relevant information about the loop's completion. - - - - - - Executes a for loop in which iterations may run in parallel. - - The start index, inclusive. - The end index, exclusive. - The delegate that is invoked once per iteration. - The exception that is thrown when the - argument is null. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - The delegate is invoked once for each value in the iteration range: - [fromInclusive, toExclusive). It is provided with the following parameters: the iteration count (an Int64), - and a ParallelLoopState instance that may be - used to break out of the loop prematurely. - - - - - Executes a for loop in which iterations may run in parallel. - - The start index, inclusive. - The end index, exclusive. - A ParallelOptions - instance that configures the behavior of this operation. - The delegate that is invoked once per iteration. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - CancellationToken in the - argument is set. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - The exception that is thrown when the - the CancellationTokenSource associated with the - the CancellationToken in the - has been disposed. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - The delegate is invoked once for each value in the iteration range: - [fromInclusive, toExclusive). It is provided with the following parameters: the iteration count (an Int32), - and a ParallelLoopState instance that may be - used to break out of the loop prematurely. - - - - - Executes a for loop in which iterations may run in parallel. - - The start index, inclusive. - The end index, exclusive. - A ParallelOptions - instance that configures the behavior of this operation. - The delegate that is invoked once per iteration. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - CancellationToken in the - argument is set. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - The exception that is thrown when the - the CancellationTokenSource associated with the - the CancellationToken in the - has been disposed. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - The delegate is invoked once for each value in the iteration range: - [fromInclusive, toExclusive). It is provided with the following parameters: the iteration count (an Int64), - and a ParallelLoopState instance that may be - used to break out of the loop prematurely. - - - - - Executes a for loop in which iterations may run in parallel. - - The type of the thread-local data. - The start index, inclusive. - The end index, exclusive. - The function delegate that returns the initial state of the local data - for each thread. - The delegate that is invoked once per iteration. - The delegate that performs a final action on the local state of each - thread. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - - The delegate is invoked once for each value in the iteration range: - [fromInclusive, toExclusive). It is provided with the following parameters: the iteration count (an Int32), - a ParallelLoopState instance that may be - used to break out of the loop prematurely, and some local state that may be shared amongst iterations - that execute on the same thread. - - - The delegate is invoked once for each thread that participates in the loop's - execution and returns the initial local state for each of those threads. These initial states are passed to the first - invocations on each thread. Then, every subsequent body invocation returns a possibly - modified state value that is passed to the next body invocation. Finally, the last body invocation on each thread returns a state value - that is passed to the delegate. The localFinally delegate is invoked once per thread to perform a final - action on each thread's local state. - - - - - - Executes a for loop in which iterations may run in parallel. Supports 64-bit indices. - - The type of the thread-local data. - The start index, inclusive. - The end index, exclusive. - The function delegate that returns the initial state of the local data - for each thread. - The delegate that is invoked once per iteration. - The delegate that performs a final action on the local state of each - thread. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - - The delegate is invoked once for each value in the iteration range: - [fromInclusive, toExclusive). It is provided with the following parameters: the iteration count (an Int64), - a ParallelLoopState instance that may be - used to break out of the loop prematurely, and some local state that may be shared amongst iterations - that execute on the same thread. - - - The delegate is invoked once for each thread that participates in the loop's - execution and returns the initial local state for each of those threads. These initial states are passed to the first - invocations on each thread. Then, every subsequent body invocation returns a possibly - modified state value that is passed to the next body invocation. Finally, the last body invocation on each thread returns a state value - that is passed to the delegate. The localFinally delegate is invoked once per thread to perform a final - action on each thread's local state. - - - - - - Executes a for loop in which iterations may run in parallel. - - The type of the thread-local data. - The start index, inclusive. - The end index, exclusive. - A ParallelOptions - instance that configures the behavior of this operation. - The function delegate that returns the initial state of the local data - for each thread. - The delegate that is invoked once per iteration. - The delegate that performs a final action on the local state of each - thread. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - CancellationToken in the - argument is set. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - The exception that is thrown when the - the CancellationTokenSource associated with the - the CancellationToken in the - has been disposed. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - - The delegate is invoked once for each value in the iteration range: - [fromInclusive, toExclusive). It is provided with the following parameters: the iteration count (an Int32), - a ParallelLoopState instance that may be - used to break out of the loop prematurely, and some local state that may be shared amongst iterations - that execute on the same thread. - - - The delegate is invoked once for each thread that participates in the loop's - execution and returns the initial local state for each of those threads. These initial states are passed to the first - invocations on each thread. Then, every subsequent body invocation returns a possibly - modified state value that is passed to the next body invocation. Finally, the last body invocation on each thread returns a state value - that is passed to the delegate. The localFinally delegate is invoked once per thread to perform a final - action on each thread's local state. - - - - - - Executes a for loop in which iterations may run in parallel. - - The type of the thread-local data. - The start index, inclusive. - The end index, exclusive. - A ParallelOptions - instance that configures the behavior of this operation. - The function delegate that returns the initial state of the local data - for each thread. - The delegate that is invoked once per iteration. - The delegate that performs a final action on the local state of each - thread. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - CancellationToken in the - argument is set. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - The exception that is thrown when the - the CancellationTokenSource associated with the - the CancellationToken in the - has been disposed. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - - The delegate is invoked once for each value in the iteration range: - [fromInclusive, toExclusive). It is provided with the following parameters: the iteration count (an Int64), - a ParallelLoopState instance that may be - used to break out of the loop prematurely, and some local state that may be shared amongst iterations - that execute on the same thread. - - - The delegate is invoked once for each thread that participates in the loop's - execution and returns the initial local state for each of those threads. These initial states are passed to the first - invocations on each thread. Then, every subsequent body invocation returns a possibly - modified state value that is passed to the next body invocation. Finally, the last body invocation on each thread returns a state value - that is passed to the delegate. The localFinally delegate is invoked once per thread to perform a final - action on each thread's local state. - - - - - - Performs the major work of the parallel for loop. It assumes that argument validation has already - been performed by the caller. This function's whole purpose in life is to enable as much reuse of - common implementation details for the various For overloads we offer. Without it, we'd end up - with lots of duplicate code. It handles: (1) simple for loops, (2) for loops that depend on - ParallelState, and (3) for loops with thread local data. - - @TODO: at some point in the future, we may want to manually inline the interesting bits into the - specific overloads above. There is some overhead associated with the extra arguments passed to - the function, and various if-checks in the code. It is also more difficult to follow what the - code does as-is because it has to handle the three flavors. - - The type of the local data. - The loop's start index, inclusive. - The loop's end index, exclusive. - A ParallelOptions instance. - The simple loop body. - The loop body for ParallelState overloads. - The loop body for thread local state overloads. - A selector function that returns new thread local state. - A cleanup function to destroy thread local state. - Only one of the body arguments may be supplied (i.e. they are exclusive). - A structure. - - - - Performs the major work of the 64-bit parallel for loop. It assumes that argument validation has already - been performed by the caller. This function's whole purpose in life is to enable as much reuse of - common implementation details for the various For overloads we offer. Without it, we'd end up - with lots of duplicate code. It handles: (1) simple for loops, (2) for loops that depend on - ParallelState, and (3) for loops with thread local data. - - @TODO: at some point in the future, we may want to manually inline the interesting bits into the - specific overloads above. There is some overhead associated with the extra arguments passed to - the function, and various if-checks in the code. It is also more difficult to follow what the - code does as-is because it has to handle the three flavors. - - The type of the local data. - The loop's start index, inclusive. - The loop's end index, exclusive. - A ParallelOptions instance. - The simple loop body. - The loop body for ParallelState overloads. - The loop body for thread local state overloads. - A selector function that returns new thread local state. - A cleanup function to destroy thread local state. - Only one of the body arguments may be supplied (i.e. they are exclusive). - A structure. - - - - Executes a for each operation on an - in which iterations may run in parallel. - - The type of the data in the source. - An enumerable data source. - The delegate that is invoked once per iteration. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - The delegate is invoked once for each element in the - enumerable. It is provided with the current element as a parameter. - - - - - Executes a for each operation on an - in which iterations may run in parallel. - - The type of the data in the source. - An enumerable data source. - A ParallelOptions - instance that configures the behavior of this operation. - The delegate that is invoked once per iteration. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - CancellationToken in the - argument is set - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - The exception that is thrown when the - the CancellationTokenSource associated with the - the CancellationToken in the - has been disposed. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - The delegate is invoked once for each element in the - enumerable. It is provided with the current element as a parameter. - - - - - Executes a for each operation on an - in which iterations may run in parallel. - - The type of the data in the source. - An enumerable data source. - The delegate that is invoked once per iteration. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - The delegate is invoked once for each element in the - enumerable. It is provided with the following parameters: the current element, - and a ParallelLoopState instance that may be - used to break out of the loop prematurely. - - - - - Executes a for each operation on an - in which iterations may run in parallel. - - The type of the data in the source. - An enumerable data source. - A ParallelOptions - instance that configures the behavior of this operation. - The delegate that is invoked once per iteration. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - CancellationToken in the - argument is set - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - The exception that is thrown when the - the CancellationTokenSource associated with the - the CancellationToken in the - has been disposed. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - The delegate is invoked once for each element in the - enumerable. It is provided with the following parameters: the current element, - and a ParallelLoopState instance that may be - used to break out of the loop prematurely. - - - - - Executes a for each operation on an - in which iterations may run in parallel. - - The type of the data in the source. - An enumerable data source. - The delegate that is invoked once per iteration. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - The delegate is invoked once for each element in the - enumerable. It is provided with the following parameters: the current element, - a ParallelLoopState instance that may be - used to break out of the loop prematurely, and the current element's index (an Int64). - - - - - Executes a for each operation on an - in which iterations may run in parallel. - - The type of the data in the source. - An enumerable data source. - A ParallelOptions - instance that configures the behavior of this operation. - The delegate that is invoked once per iteration. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - CancellationToken in the - argument is set - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - The exception that is thrown when the - the CancellationTokenSource associated with the - the CancellationToken in the - has been disposed. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - The delegate is invoked once for each element in the - enumerable. It is provided with the following parameters: the current element, - a ParallelLoopState instance that may be - used to break out of the loop prematurely, and the current element's index (an Int64). - - - - - Executes a for each operation on an - in which iterations may run in parallel. - - The type of the data in the source. - The type of the thread-local data. - An enumerable data source. - The function delegate that returns the initial state of the local data - for each thread. - The delegate that is invoked once per iteration. - The delegate that performs a final action on the local state of each - thread. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - - The delegate is invoked once for each element in the - enumerable. It is provided with the following parameters: the current element, - a ParallelLoopState instance that may be - used to break out of the loop prematurely, and some local state that may be shared amongst iterations - that execute on the same thread. - - - The delegate is invoked once for each thread that participates in the loop's - execution and returns the initial local state for each of those threads. These initial states are passed to the first - invocations on each thread. Then, every subsequent body invocation returns a possibly - modified state value that is passed to the next body invocation. Finally, the last body invocation on each thread returns a state value - that is passed to the delegate. The localFinally delegate is invoked once per thread to perform a final - action on each thread's local state. - - - - - - Executes a for each operation on an - in which iterations may run in parallel. - - The type of the data in the source. - The type of the thread-local data. - An enumerable data source. - A ParallelOptions - instance that configures the behavior of this operation. - The function delegate that returns the initial state of the local data - for each thread. - The delegate that is invoked once per iteration. - The delegate that performs a final action on the local state of each - thread. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - CancellationToken in the - argument is set - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - The exception that is thrown when the - the CancellationTokenSource associated with the - the CancellationToken in the - has been disposed. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - - The delegate is invoked once for each element in the - enumerable. It is provided with the following parameters: the current element, - a ParallelLoopState instance that may be - used to break out of the loop prematurely, and some local state that may be shared amongst iterations - that execute on the same thread. - - - The delegate is invoked once for each thread that participates in the loop's - execution and returns the initial local state for each of those threads. These initial states are passed to the first - invocations on each thread. Then, every subsequent body invocation returns a possibly - modified state value that is passed to the next body invocation. Finally, the last body invocation on each thread returns a state value - that is passed to the delegate. The localFinally delegate is invoked once per thread to perform a final - action on each thread's local state. - - - - - - Executes a for each operation on an - in which iterations may run in parallel. - - The type of the data in the source. - The type of the thread-local data. - An enumerable data source. - The function delegate that returns the initial state of the local data - for each thread. - The delegate that is invoked once per iteration. - The delegate that performs a final action on the local state of each - thread. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - - The delegate is invoked once for each element in the - enumerable. It is provided with the following parameters: the current element, - a ParallelLoopState instance that may be - used to break out of the loop prematurely, the current element's index (an Int64), and some local - state that may be shared amongst iterations that execute on the same thread. - - - The delegate is invoked once for each thread that participates in the loop's - execution and returns the initial local state for each of those threads. These initial states are passed to the first - invocations on each thread. Then, every subsequent body invocation returns a possibly - modified state value that is passed to the next body invocation. Finally, the last body invocation on each thread returns a state value - that is passed to the delegate. The localFinally delegate is invoked once per thread to perform a final - action on each thread's local state. - - - - - - Executes a for each operation on an - in which iterations may run in parallel. - - The type of the data in the source. - The type of the thread-local data. - An enumerable data source. - A ParallelOptions - instance that configures the behavior of this operation. - The function delegate that returns the initial state of the local data - for each thread. - The delegate that is invoked once per iteration. - The delegate that performs a final action on the local state of each - thread. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - CancellationToken in the - argument is set - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - The exception that is thrown when the - the CancellationTokenSource associated with the - the CancellationToken in the - has been disposed. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - - The delegate is invoked once for each element in the - enumerable. It is provided with the following parameters: the current element, - a ParallelLoopState instance that may be - used to break out of the loop prematurely, the current element's index (an Int64), and some local - state that may be shared amongst iterations that execute on the same thread. - - - The delegate is invoked once for each thread that participates in the loop's - execution and returns the initial local state for each of those threads. These initial states are passed to the first - invocations on each thread. Then, every subsequent body invocation returns a possibly - modified state value that is passed to the next body invocation. Finally, the last body invocation on each thread returns a state value - that is passed to the delegate. The localFinally delegate is invoked once per thread to perform a final - action on each thread's local state. - - - - - - Performs the major work of the parallel foreach loop. It assumes that argument validation has - already been performed by the caller. This function's whole purpose in life is to enable as much - reuse of common implementation details for the various For overloads we offer. Without it, we'd - end up with lots of duplicate code. It handles: (1) simple foreach loops, (2) foreach loops that - depend on ParallelState, and (3) foreach loops that access indices, (4) foreach loops with thread - local data, and any necessary permutations thereof. - - @TODO: at some point in the future, we may want to manually inline the interesting bits into the - specific overloads above. There is some overhead associated with the extra arguments passed to - the function, and various if-checks in the code. It is also more difficult to follow what the - code does as-is because it has to handle the all flavors. - - The type of the source data. - The type of the local data. - An enumerable data source. - ParallelOptions instance to use with this ForEach-loop - The simple loop body. - The loop body for ParallelState overloads. - The loop body for ParallelState/indexed overloads. - The loop body for ParallelState/thread local state overloads. - The loop body for ParallelState/indexed/thread local state overloads. - A selector function that returns new thread local state. - A cleanup function to destroy thread local state. - Only one of the bodyXX arguments may be supplied (i.e. they are exclusive). - A structure. - - - - A fast path for the more general ForEachWorker method above. This uses ldelem instructions to - access the individual elements of the array, which will be faster. - - The type of the source data. - The type of the local data. - An array data source. - The options to use for execution. - The simple loop body. - The loop body for ParallelState overloads. - The loop body for indexed/ParallelLoopState overloads. - The loop body for local/ParallelLoopState overloads. - The loop body for the most generic overload. - A selector function that returns new thread local state. - A cleanup function to destroy thread local state. - A structure. - - - - A fast path for the more general ForEachWorker method above. This uses IList<T>'s indexer - capabilities to access the individual elements of the list rather than an enumerator. - - The type of the source data. - The type of the local data. - A list data source. - The options to use for execution. - The simple loop body. - The loop body for ParallelState overloads. - The loop body for indexed/ParallelLoopState overloads. - The loop body for local/ParallelLoopState overloads. - The loop body for the most generic overload. - A selector function that returns new thread local state. - A cleanup function to destroy thread local state. - A structure. - - - - Executes a for each operation on a - Partitioner in which iterations may run in parallel. - - The type of the elements in . - The Partitioner that contains the original data source. - The delegate that is invoked once per iteration. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - SupportsDynamicPartitions property in the Partitioner returns - false. - The exception that is thrown when any - methods in the Partitioner return null. - The exception that is thrown when the - GetPartitions() method in the Partitioner does not return - the correct number of partitions. - The exception that is thrown when the - GetPartitions() method in the Partitioner returns an IList - with at least one null value. - The exception that is thrown when the - GetDynamicPartitions() method in the Partitioner returns an - IEnumerable whose GetEnumerator() method returns null. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - - The Partitioner is used to retrieve - the elements to be processed, in place of the original data source. If the current element's - index is desired, the source must be an - OrderablePartitioner. - - - The delegate is invoked once for each element in the - Partitioner. It is provided with the current element as a parameter. - - - - - - Executes a for each operation on a - Partitioner in which iterations may run in parallel. - - The type of the elements in . - The Partitioner that contains the original data source. - The delegate that is invoked once per iteration. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - SupportsDynamicPartitions property in the Partitioner returns - false. - The exception that is thrown when any - methods in the Partitioner return null. - The exception that is thrown when the - GetPartitions() method in the Partitioner does not return - the correct number of partitions. - The exception that is thrown when the - GetPartitions() method in the Partitioner returns an IList - with at least one null value. - The exception that is thrown when the - GetDynamicPartitions() method in the Partitioner returns an - IEnumerable whose GetEnumerator() method returns null. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - - The Partitioner is used to retrieve - the elements to be processed, in place of the original data source. If the current element's - index is desired, the source must be an - OrderablePartitioner. - - - The delegate is invoked once for each element in the - Partitioner. It is provided with the following parameters: the current element, - and a ParallelLoopState instance that may be - used to break out of the loop prematurely. - - - - - - Executes a for each operation on a - OrderablePartitioner in which iterations may run in parallel. - - The type of the elements in . - The OrderablePartitioner that contains the original data source. - The delegate that is invoked once per iteration. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - SupportsDynamicPartitions property in the OrderablePartitioner returns - false. - The exception that is thrown when the - KeysNormalized property in the OrderablePartitioner returns - false. - The exception that is thrown when any - methods in the OrderablePartitioner return null. - The exception that is thrown when the - GetPartitions() or GetOrderablePartitions() methods in the - OrderablePartitioner do not return the correct number of partitions. - The exception that is thrown when the - GetPartitions() or GetOrderablePartitions() methods in the - OrderablePartitioner return an IList with at least one null value. - The exception that is thrown when the - GetDynamicPartitions() or GetDynamicOrderablePartitions() methods in the - OrderablePartitioner return an IEnumerable whose GetEnumerator() method returns null. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - - The Partitioner is used to retrieve - the elements to be processed, in place of the original data source. If the current element's - index is desired, the source must be an - OrderablePartitioner. - - - The delegate is invoked once for each element in the - Partitioner. It is provided with the following parameters: the current element, - a ParallelLoopState instance that may be - used to break out of the loop prematurely, and the current element's index (an Int64). - - - - - - Executes a for each operation on a - Partitioner in which iterations may run in parallel. - - The type of the elements in . - The type of the thread-local data. - The Partitioner that contains the original data source. - The function delegate that returns the initial state of the local data - for each thread. - The delegate that is invoked once per iteration. - The delegate that performs a final action on the local state of each - thread. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - SupportsDynamicPartitions property in the Partitioner returns - false. - The exception that is thrown when any - methods in the Partitioner return null. - The exception that is thrown when the - GetPartitions() method in the Partitioner does not return - the correct number of partitions. - The exception that is thrown when the - GetPartitions() method in the Partitioner returns an IList - with at least one null value. - The exception that is thrown when the - GetDynamicPartitions() method in the Partitioner returns an - IEnumerable whose GetEnumerator() method returns null. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - - The Partitioner is used to retrieve - the elements to be processed, in place of the original data source. If the current element's - index is desired, the source must be an - OrderablePartitioner. - - - The delegate is invoked once for each element in the - Partitioner. It is provided with the following parameters: the current element, - a ParallelLoopState instance that may be - used to break out of the loop prematurely, and some local state that may be shared amongst iterations - that execute on the same thread. - - - The delegate is invoked once for each thread that participates in the loop's - execution and returns the initial local state for each of those threads. These initial states are passed to the first - invocations on each thread. Then, every subsequent body invocation returns a possibly - modified state value that is passed to the next body invocation. Finally, the last body invocation on each thread returns a state value - that is passed to the delegate. The localFinally delegate is invoked once per thread to perform a final - action on each thread's local state. - - - - - - Executes a for each operation on a - OrderablePartitioner in which iterations may run in parallel. - - The type of the elements in . - The type of the thread-local data. - The OrderablePartitioner that contains the original data source. - The function delegate that returns the initial state of the local data - for each thread. - The delegate that is invoked once per iteration. - The delegate that performs a final action on the local state of each - thread. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - SupportsDynamicPartitions property in the OrderablePartitioner returns - false. - The exception that is thrown when the - KeysNormalized property in the OrderablePartitioner returns - false. - The exception that is thrown when any - methods in the OrderablePartitioner return null. - The exception that is thrown when the - GetPartitions() or GetOrderablePartitions() methods in the - OrderablePartitioner do not return the correct number of partitions. - The exception that is thrown when the - GetPartitions() or GetOrderablePartitions() methods in the - OrderablePartitioner return an IList with at least one null value. - The exception that is thrown when the - GetDynamicPartitions() or GetDynamicOrderablePartitions() methods in the - OrderablePartitioner return an IEnumerable whose GetEnumerator() method returns null. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - - The Partitioner is used to retrieve - the elements to be processed, in place of the original data source. If the current element's - index is desired, the source must be an - OrderablePartitioner. - - - The delegate is invoked once for each element in the - Partitioner. It is provided with the following parameters: the current element, - a ParallelLoopState instance that may be - used to break out of the loop prematurely, the current element's index (an Int64), and some local - state that may be shared amongst iterations that execute on the same thread. - - - The delegate is invoked once for each thread that participates in the loop's - execution and returns the initial local state for each of those threads. These initial states are passed to the first - invocations on each thread. Then, every subsequent body invocation returns a possibly - modified state value that is passed to the next body invocation. Finally, the last body invocation on each thread returns a state value - that is passed to the delegate. The localFinally delegate is invoked once per thread to perform a final - action on each thread's local state. - - - - - - Executes a for each operation on a - Partitioner in which iterations may run in parallel. - - The type of the elements in . - The Partitioner that contains the original data source. - A ParallelOptions - instance that configures the behavior of this operation. - The delegate that is invoked once per iteration. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - CancellationToken in the - argument is set - The exception that is thrown when the - SupportsDynamicPartitions property in the Partitioner returns - false. - The exception that is thrown when any - methods in the Partitioner return null. - The exception that is thrown when the - GetPartitions() method in the Partitioner does not return - the correct number of partitions. - The exception that is thrown when the - GetPartitions() method in the Partitioner returns an IList - with at least one null value. - The exception that is thrown when the - GetDynamicPartitions() method in the Partitioner returns an - IEnumerable whose GetEnumerator() method returns null. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - The exception that is thrown when the - the CancellationTokenSource associated with the - the CancellationToken in the - has been disposed. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - - The Partitioner is used to retrieve - the elements to be processed, in place of the original data source. If the current element's - index is desired, the source must be an - OrderablePartitioner. - - - The delegate is invoked once for each element in the - Partitioner. It is provided with the current element as a parameter. - - - - - - Executes a for each operation on a - Partitioner in which iterations may run in parallel. - - The type of the elements in . - The Partitioner that contains the original data source. - A ParallelOptions - instance that configures the behavior of this operation. - The delegate that is invoked once per iteration. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - CancellationToken in the - argument is set - The exception that is thrown when the - SupportsDynamicPartitions property in the Partitioner returns - false. - The exception that is thrown when any - methods in the Partitioner return null. - The exception that is thrown when the - GetPartitions() method in the Partitioner does not return - the correct number of partitions. - The exception that is thrown when the - GetPartitions() method in the Partitioner returns an IList - with at least one null value. - The exception that is thrown when the - GetDynamicPartitions() method in the Partitioner returns an - IEnumerable whose GetEnumerator() method returns null. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - The exception that is thrown when the - the CancellationTokenSource associated with the - the CancellationToken in the - has been disposed. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - - The Partitioner is used to retrieve - the elements to be processed, in place of the original data source. If the current element's - index is desired, the source must be an - OrderablePartitioner. - - - The delegate is invoked once for each element in the - Partitioner. It is provided with the following parameters: the current element, - and a ParallelLoopState instance that may be - used to break out of the loop prematurely. - - - - - - Executes a for each operation on a - OrderablePartitioner in which iterations may run in parallel. - - The type of the elements in . - The OrderablePartitioner that contains the original data source. - A ParallelOptions - instance that configures the behavior of this operation. - The delegate that is invoked once per iteration. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - CancellationToken in the - argument is set - The exception that is thrown when the - SupportsDynamicPartitions property in the OrderablePartitioner returns - false. - The exception that is thrown when the - KeysNormalized property in the OrderablePartitioner returns - false. - The exception that is thrown when any - methods in the OrderablePartitioner return null. - The exception that is thrown when the - GetPartitions() or GetOrderablePartitions() methods in the - OrderablePartitioner do not return the correct number of partitions. - The exception that is thrown when the - GetPartitions() or GetOrderablePartitions() methods in the - OrderablePartitioner return an IList with at least one null value. - The exception that is thrown when the - GetDynamicPartitions() or GetDynamicOrderablePartitions() methods in the - OrderablePartitioner return an IEnumerable whose GetEnumerator() method returns null. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - The exception that is thrown when the - the CancellationTokenSource associated with the - the CancellationToken in the - has been disposed. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - - The Partitioner is used to retrieve - the elements to be processed, in place of the original data source. If the current element's - index is desired, the source must be an - OrderablePartitioner. - - - The delegate is invoked once for each element in the - Partitioner. It is provided with the following parameters: the current element, - a ParallelLoopState instance that may be - used to break out of the loop prematurely, and the current element's index (an Int64). - - - - - - Executes a for each operation on a - Partitioner in which iterations may run in parallel. - - The type of the elements in . - The type of the thread-local data. - The Partitioner that contains the original data source. - A ParallelOptions - instance that configures the behavior of this operation. - The function delegate that returns the initial state of the local data - for each thread. - The delegate that is invoked once per iteration. - The delegate that performs a final action on the local state of each - thread. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - CancellationToken in the - argument is set - The exception that is thrown when the - SupportsDynamicPartitions property in the Partitioner returns - false. - The exception that is thrown when any - methods in the Partitioner return null. - The exception that is thrown when the - GetPartitions() method in the Partitioner does not return - the correct number of partitions. - The exception that is thrown when the - GetPartitions() method in the Partitioner returns an IList - with at least one null value. - The exception that is thrown when the - GetDynamicPartitions() method in the Partitioner returns an - IEnumerable whose GetEnumerator() method returns null. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - The exception that is thrown when the - the CancellationTokenSource associated with the - the CancellationToken in the - has been disposed. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - - The Partitioner is used to retrieve - the elements to be processed, in place of the original data source. If the current element's - index is desired, the source must be an - OrderablePartitioner. - - - The delegate is invoked once for each element in the - Partitioner. It is provided with the following parameters: the current element, - a ParallelLoopState instance that may be - used to break out of the loop prematurely, and some local state that may be shared amongst iterations - that execute on the same thread. - - - The delegate is invoked once for each thread that participates in the loop's - execution and returns the initial local state for each of those threads. These initial states are passed to the first - invocations on each thread. Then, every subsequent body invocation returns a possibly - modified state value that is passed to the next body invocation. Finally, the last body invocation on each thread returns a state value - that is passed to the delegate. The localFinally delegate is invoked once per thread to perform a final - action on each thread's local state. - - - - - - Executes a for each operation on a - OrderablePartitioner in which iterations may run in parallel. - - The type of the elements in . - The type of the thread-local data. - The OrderablePartitioner that contains the original data source. - A ParallelOptions - instance that configures the behavior of this operation. - The function delegate that returns the initial state of the local data - for each thread. - The delegate that is invoked once per iteration. - The delegate that performs a final action on the local state of each - thread. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - CancellationToken in the - argument is set - The exception that is thrown when the - SupportsDynamicPartitions property in the OrderablePartitioner returns - false. - The exception that is thrown when the - KeysNormalized property in the OrderablePartitioner returns - false. - The exception that is thrown when any - methods in the OrderablePartitioner return null. - The exception that is thrown when the - GetPartitions() or GetOrderablePartitions() methods in the - OrderablePartitioner do not return the correct number of partitions. - The exception that is thrown when the - GetPartitions() or GetOrderablePartitions() methods in the - OrderablePartitioner return an IList with at least one null value. - The exception that is thrown when the - GetDynamicPartitions() or GetDynamicOrderablePartitions() methods in the - OrderablePartitioner return an IEnumerable whose GetEnumerator() method returns null. - The exception that is thrown to contain an exception - thrown from one of the specified delegates. - The exception that is thrown when the - the CancellationTokenSource associated with the - the CancellationToken in the - has been disposed. - A ParallelLoopResult structure - that contains information on what portion of the loop completed. - - - The Partitioner is used to retrieve - the elements to be processed, in place of the original data source. If the current element's - index is desired, the source must be an - OrderablePartitioner. - - - The delegate is invoked once for each element in the - Partitioner. It is provided with the following parameters: the current element, - a ParallelLoopState instance that may be - used to break out of the loop prematurely, the current element's index (an Int64), and some local - state that may be shared amongst iterations that execute on the same thread. - - - The delegate is invoked once for each thread that participates in the loop's - execution and returns the initial local state for each of those threads. These initial states are passed to the first - invocations on each thread. Then, every subsequent body invocation returns a possibly - modified state value that is passed to the next body invocation. Finally, the last body invocation on each thread returns a state value - that is passed to the delegate. The localFinally delegate is invoked once per thread to perform a final - action on each thread's local state. - - - - - - Internal utility function that implements the OCE filtering behavior for all Parallel.* APIs. - Throws a single OperationCancelledException object with the token if the Exception collection only contains - OperationCancelledExceptions with the given CancellationToken. - - - The exception collection to filter - The CancellationToken expected on all inner exceptions - - - - - Enables iterations of loops to interact with - other iterations. - - - - - Communicates that the loop should cease execution at the system's earliest - convenience. - - - The method was previously called. and may not be used in combination by iterations of the same loop. - - - - may be used to communicate to the loop that no other iterations need be run. - For long-running iterations that may already be executing, causes - to return true for all other iterations of the loop, such that another iteration may check and exit early if it's observed to be true. - - - is typically employed in search-based algorithms, where once a result is found, - no other iterations need be executed. - - - - - - Communicates that the loop should cease execution at the system's earliest - convenience of iterations beyond the current iteration. - - - The method was previously called. and - may not be used in combination by iterations of the same loop. - - - - may be used to communicate to the loop that no other iterations after the - current iteration need be run. For example, if is called from the 100th - iteration of a for loop iterating in parallel from 0 to 1000, all iterations less than 100 should - still be run, but the iterations from 101 through to 1000 are not necessary. - - - For long-running iterations that may already be executing, causes - to be set to the current iteration's index if the current index is less than the current value of - . - - - is typically employed in search-based algorithms where an ordering is - present in the data source. - - - - - - Internal/virtual support for ShouldExitCurrentIteration. - - - - - Gets whether the current iteration of the loop should exit based - on requests made by this or other iterations. - - - When an iteration of a loop calls or , or - when one throws an exception, or when the loop is canceled, the class will proactively - attempt to prohibit additional iterations of the loop from starting execution. - However, there may be cases where it is unable to prevent additional iterations from starting. - It may also be the case that a long-running iteration has already begun execution. In such - cases, iterations may explicitly check the property and - cease execution if the property returns true. - - - - - Gets whether any iteration of the loop has called . - - - - - Gets whether any iteration of the loop has thrown an exception that went unhandled by that - iteration. - - - - - Internal/virtual support for LowestBreakIteration. - - - - - Gets the lowest iteration of the loop from which was called. - - - If no iteration of the loop called , this property will return null. - - - - - Internal constructor to ensure an instance isn't created by users. - - A flag shared among all threads participating - in the execution of a certain loop. - - - - Communicates that parallel tasks should stop when they reach a specified iteration element. - (which is CurrentIteration of the caller). - - Break() called after Stop(). - - This is shared with all other concurrent threads in the system which are participating in the - loop's execution. After calling Break(), no additional iterations will be executed on - the current thread, and other worker threads will execute once they get beyond the calling iteration. - - - - - Tracks the current loop iteration for the owning task. - This is used to compute whether or not the task should - terminate early due to a Break() call. - - - - - Returns true if we should be exiting from the current iteration - due to Stop(), Break() or exception. - - - - - Returns the lowest iteration at which Break() has been called, or - null if Break() has not yet been called. - - - - - Allows independent iterations of a parallel loop to interact with other iterations. - - - - - Internal constructor to ensure an instance isn't created by users. - - A flag shared among all threads participating - in the execution of a certain loop. - - - - Communicates that parallel tasks should stop when they reach a specified iteration element. - (which is CurrentIteration of the caller). - - Break() called after Stop(). - - Atomically sets shared StoppedBroken flag to BROKEN, then atomically sets shared - LowestBreakIteration to CurrentIteration, but only if CurrentIteration is less than - LowestBreakIteration. - - - - - Tracks the current loop iteration for the owning task. - This is used to compute whether or not the task should - terminate early due to a Break() call. - - - - - Returns true if we should be exiting from the current iteration - due to Stop(), Break() or exception. - - - - - Returns the lowest iteration at which Break() has been called, or - null if Break() has not yet been called. - - - - - State information that is common between ParallelStateFlags class - and ParallelStateFlags64 class. - - - - - An internal class used to share accounting information in 32-bit versions - of For()/ForEach() loops. - - - - - Lets the caller know whether or not to prematurely exit the For/ForEach loop. - If this returns true, then exit the loop. Otherwise, keep going. - - The caller's current iteration point - in the loop. - - The loop should exit on any one of the following conditions: - (1) Stop() has been called by one or more tasks. - (2) An exception has been raised by one or more tasks. - (3) Break() has been called by one or more tasks, and - CallerIteration exceeds the (lowest) iteration at which - Break() was called. - (4) The loop was canceled. - - - - - An internal class used to share accounting information in 64-bit versions - of For()/ForEach() loops. - - - - - Lets the caller know whether or not to prematurely exit the For/ForEach loop. - If this returns true, then exit the loop. Otherwise, keep going. - - The caller's current iteration point - in the loop. - - The loop should exit on any one of the following conditions: - (1) Stop() has been called by one or more tasks. - (2) An exception has been raised by one or more tasks. - (3) Break() has been called by one or more tasks, and - CallerIteration exceeds the (lowest) iteration at which - Break() was called. - (4) The loop has been canceled. - - - - - Provides completion status on the execution of a loop. - - - If returns true, then the loop ran to completion, such that all iterations - of the loop were executed. If returns false and returns null, a call to was used to end the loop prematurely. If returns false and returns a non-null integral - value, was used to end the loop prematurely. - - - - - Gets whether the loop ran to completion, such that all iterations of the loop were executed - and the loop didn't receive a request to end prematurely. - - - - - Gets the index of the lowest iteration from which - was called. - - - If was not employed, this property will - return null. - - - - - Utility class for allocating structs as heap variables - - - - - Represents an index range - - - - - The RangeWorker struct wraps the state needed by a task that services the parallel loop - - - - - Initializes a RangeWorker struct - - - - - Implements the core work search algorithm that will be used for this range worker. - - - Usage pattern is: - 1) the thread associated with this rangeworker calls FindNewWork - 2) if we return true, the worker uses the nFromInclusiveLocal and nToExclusiveLocal values - to execute the sequential loop - 3) if we return false it means there is no more work left. It's time to quit. - - - - - 32 bit integer version of FindNewWork. Assumes the ranges were initialized with 32 bit values. - - - - - Represents the entire loop operation, keeping track of workers and ranges. - - - The usage pattern is: - 1) The Parallel loop entry function (ForWorker) creates an instance of this class - 2) Every thread joining to service the parallel loop calls RegisterWorker to grab a - RangeWorker struct to wrap the state it will need to find and execute work, - and they keep interacting with that struct until the end of the loop - - - - Initializes a RangeManager with the given loop parameters, and the desired number of outer ranges - - - - - The function that needs to be called by each new worker thread servicing the parallel loop - in order to get a RangeWorker struct that wraps the state for finding and executing indices - - - - - Represents an asynchronous operation that produces a result at some time in the future. - - - The type of the result produced by this . - - - - instances may be created in a variety of ways. The most common approach is by - using the task's property to retrieve a instance that can be used to create tasks for several - purposes. For example, to create a that runs a function, the factory's StartNew - method may be used: - - // C# - var t = Task<int>.Factory.StartNew(() => GenerateResult()); - - or - - var t = Task.Factory.StartNew(() => GenerateResult()); - - ' Visual Basic - Dim t = Task<int>.Factory.StartNew(Function() GenerateResult()) - - or - - Dim t = Task.Factory.StartNew(Function() GenerateResult()) - - - - The class also provides constructors that initialize the task but that do not - schedule it for execution. For performance reasons, the StartNew method should be the - preferred mechanism for creating and scheduling computational tasks, but for scenarios where creation - and scheduling must be separated, the constructors may be used, and the task's - Start - method may then be used to schedule the task for execution at a later time. - - - All members of , except for - Dispose, are thread-safe - and may be used from multiple threads concurrently. - - - - - - Represents an asynchronous operation. - - - - instances may be created in a variety of ways. The most common approach is by - using the Task type's property to retrieve a instance that can be used to create tasks for several - purposes. For example, to create a that runs an action, the factory's StartNew - method may be used: - - // C# - var t = Task.Factory.StartNew(() => DoAction()); - - ' Visual Basic - Dim t = Task.Factory.StartNew(Function() DoAction()) - - - - The class also provides constructors that initialize the Task but that do not - schedule it for execution. For performance reasons, TaskFactory's StartNew method should be the - preferred mechanism for creating and scheduling computational tasks, but for scenarios where creation - and scheduling must be separated, the constructors may be used, and the task's - method may then be used to schedule the task for execution at a later time. - - - All members of , except for , are thread-safe - and may be used from multiple threads concurrently. - - - For operations that return values, the class - should be used. - - - For developers implementing custom debuggers, several internal and private members of Task may be - useful (these may change from release to release). The Int32 m_taskId field serves as the backing - store for the property, however accessing this field directly from a debugger may be - more efficient than accessing the same value through the property's getter method (the - s_taskIdCounter Int32 counter is used to retrieve the next available ID for a Task). Similarly, the - Int32 m_stateFlags field stores information about the current lifecycle stage of the Task, - information also accessible through the property. The m_action System.Object - field stores a reference to the Task's delegate, and the m_stateObject System.Object field stores the - async state passed to the Task by the developer. Finally, for debuggers that parse stack frames, the - InternalWait method serves a potential marker for when a Task is entering a wait operation. - - - - - - A type initializer that runs with the appropriate permissions. - - - - - Initializes a new with the specified action. - - The delegate that represents the code to execute in the Task. - The argument is null. - - - - Initializes a new with the specified action and CancellationToken. - - The delegate that represents the code to execute in the Task. - The CancellationToken - that will be assigned to the new Task. - The argument is null. - The provided CancellationToken - has already been disposed. - - - - - Initializes a new with the specified action and creation options. - - The delegate that represents the code to execute in the task. - - The TaskCreationOptions used to - customize the Task's behavior. - - - The argument is null. - - - The argument specifies an invalid value for . - - - - - Initializes a new with the specified action and creation options. - - The delegate that represents the code to execute in the task. - The that will be assigned to the new task. - - The TaskCreationOptions used to - customize the Task's behavior. - - - The argument is null. - - - The argument specifies an invalid value for . - - The provided CancellationToken - has already been disposed. - - - - - Initializes a new with the specified action and state. - - The delegate that represents the code to execute in the task. - An object representing data to be used by the action. - - The argument is null. - - - - - Initializes a new with the specified action, state, snd options. - - The delegate that represents the code to execute in the task. - An object representing data to be used by the action. - The that will be assigned to the new task. - - The argument is null. - - The provided CancellationToken - has already been disposed. - - - - - Initializes a new with the specified action, state, snd options. - - The delegate that represents the code to execute in the task. - An object representing data to be used by the action. - - The TaskCreationOptions used to - customize the Task's behavior. - - - The argument is null. - - - The argument specifies an invalid value for . - - - - - Initializes a new with the specified action, state, snd options. - - The delegate that represents the code to execute in the task. - An object representing data to be used by the action. - The that will be assigned to the new task. - - The TaskCreationOptions used to - customize the Task's behavior. - - - The argument is null. - - - The argument specifies an invalid value for . - - The provided CancellationToken - has already been disposed. - - - - - An internal constructor used by the factory methods on task and its descendent(s). - This variant does not capture the ExecutionContext; it is up to the caller to do that. - - An action to execute. - Optional state to pass to the action. - Parent of Task. - A CancellationToken for the task. - A task scheduler under which the task will run. - Options to control its execution. - Internal options to control its execution - - - - Common logic used by the following internal ctors: - Task() - Task(object action, object state, Task parent, TaskCreationOptions options, TaskScheduler taskScheduler) - - ASSUMES THAT m_creatingTask IS ALREADY SET. - - - Action for task to execute. - Object to which to pass to action (may be null) - Task scheduler on which to run thread (only used by continuation tasks). - A CancellationToken for the Task. - Options to customize behavior of Task. - Internal options to customize behavior of Task. - - - - Checks if we registered a CT callback during construction, and deregisters it. - This should be called when we know the registration isn't useful anymore. Specifically from Finish() if the task has completed - successfully or with an exception. - - - - - Captures the ExecutionContext so long as flow isn't suppressed. - - A stack crawl mark pointing to the frame of the caller. - - - - Internal function that will be called by a new child task to add itself to - the children list of the parent (this). - - Since a child task can only be created from the thread executing the action delegate - of this task, reentrancy is neither required nor supported. This should not be called from - anywhere other than the task construction/initialization codepaths. - - - - - Starts the , scheduling it for execution to the current TaskScheduler. - - - A task may only be started and run only once. Any attempts to schedule a task a second time - will result in an exception. - - - The is not in a valid state to be started. It may have already been started, - executed, or canceled, or it may have been created in a manner that doesn't support direct - scheduling. - - - The instance has been disposed. - - - - - Starts the , scheduling it for execution to the specified TaskScheduler. - - - A task may only be started and run only once. Any attempts to schedule a task a second time will - result in an exception. - - - The TaskScheduler with which to associate - and execute this task. - - - The argument is null. - - - The is not in a valid state to be started. It may have already been started, - executed, or canceled, or it may have been created in a manner that doesn't support direct - scheduling. - - - The instance has been disposed. - - - - - Runs the synchronously on the current TaskScheduler. - - - - A task may only be started and run only once. Any attempts to schedule a task a second time will - result in an exception. - - - Tasks executed with will be associated with the current TaskScheduler. - - - If the target scheduler does not support running this Task on the current thread, the Task will - be scheduled for execution on the scheduler, and the current thread will block until the - Task has completed execution. - - - - The is not in a valid state to be started. It may have already been started, - executed, or canceled, or it may have been created in a manner that doesn't support direct - scheduling. - - - The instance has been disposed. - - - - - Runs the synchronously on the scheduler provided. - - - - A task may only be started and run only once. Any attempts to schedule a task a second time will - result in an exception. - - - If the target scheduler does not support running this Task on the current thread, the Task will - be scheduled for execution on the scheduler, and the current thread will block until the - Task has completed execution. - - - - The is not in a valid state to be started. It may have already been started, - executed, or canceled, or it may have been created in a manner that doesn't support direct - scheduling. - - - The instance has been disposed. - - The parameter - is null. - The scheduler on which to attempt to run this task inline. - - - - Throws an exception if the task has been disposed, and hence can no longer be accessed. - - The task has been disposed. - - - - Sets the internal completion event. - - - - - Disposes the , releasing all of its unmanaged resources. - - - Unlike most of the members of , this method is not thread-safe. - Also, may only be called on a that is in one of - the final states: RanToCompletion, - Faulted, or - Canceled. - - - The exception that is thrown if the is not in - one of the final states: RanToCompletion, - Faulted, or - Canceled. - - - - - Disposes the , releasing all of its unmanaged resources. - - - A Boolean value that indicates whether this method is being called due to a call to . - - - Unlike most of the members of , this method is not thread-safe. - - - - - Schedules the task for execution. - - If true, TASK_STATE_STARTED bit is turned on in - an atomic fashion, making sure that TASK_STATE_CANCELED does not get set - underneath us. If false, TASK_STATE_STARTED bit is OR-ed right in. This - allows us to streamline things a bit for StartNew(), where competing cancellations - are not a problem. - - - - Adds an exception to the list of exceptions this task has thrown. - - An object representing either an Exception or a collection of Exceptions. - - - - Returns a list of exceptions by aggregating the holder's contents. Or null if - no exceptions have been thrown. - - Whether to include a TCE if cancelled. - An aggregate exception, or null if no exceptions have been caught. - - - - Throws an aggregate exception if the task contains exceptions. - - - - - Checks whether this is an attached task, and whether we are being called by the parent task. - And sets the TASK_STATE_EXCEPTIONOBSERVEDBYPARENT status flag based on that. - - This is meant to be used internally when throwing an exception, and when WaitAll is gathering - exceptions for tasks it waited on. If this flag gets set, the implicit wait on children - will skip exceptions to prevent duplication. - - This should only be called when this task has completed with an exception - - - - - - Signals completion of this particular task. - - The bUserDelegateExecuted parameter indicates whether this Finish() call comes following the - full execution of the user delegate. - - If bUserDelegateExecuted is false, it mean user delegate wasn't invoked at all (either due to - a cancellation request, or because this task is a promise style Task). In this case, the steps - involving child tasks (i.e. WaitForChildren) will be skipped. - - - - - - FinishStageTwo is to be executed as soon as we known there are no more children to complete. - It can happen i) either on the thread that originally executed this task (if no children were spawned, or they all completed by the time this task's delegate quit) - ii) or on the thread that executed the last child. - - - - - Final stage of the task completion code path. Notifies the parent (if any) that another of its childre are done, and runs continuations. - This function is only separated out from FinishStageTwo because these two operations are also needed to be called from CancellationCleanupLogic() - - - - - This is called by children of this task when they are completed. - - - - - This is to be called just before the task does its final state transition. - It traverses the list of exceptional children, and appends their aggregate exceptions into this one's exception list - - - - - Special purpose Finish() entry point to be used when the task delegate throws a ThreadAbortedException - This makes a note in the state flags so that we avoid any costly synchronous operations in the finish codepath - such as inlined continuations - - - Indicates whether the ThreadAbortException was added to this task's exception holder. - This should always be true except for the case of non-root self replicating task copies. - - Whether the delegate was executed. - - - - Executes the task. This method will only be called once, and handles bookeeping associated with - self-replicating tasks, in addition to performing necessary exception marshaling. - - The task has already been disposed. - - - - IThreadPoolWorkItem override, which is the entry function for this task when the TP scheduler decides to run it. - - - - - - The ThreadPool calls this if a ThreadAbortException is thrown while trying to execute this workitem. This may occur - before Task would otherwise be able to observe it. - - - - - Outermost entry function to execute this task. Handles all aspects of executing a task on the caller thread. - Currently this is called by IThreadPoolWorkItem.ExecuteWorkItem(), and TaskManager.TryExecuteInline. - - - Performs atomic updates to prevent double execution. Should only be set to true - in codepaths servicing user provided TaskSchedulers. The ConcRT or ThreadPool schedulers don't need this. - - - - The actual code which invokes the body of the task. This can be overriden in derived types. - - - - - Alternate InnerInvoke prototype to be called from ExecuteSelfReplicating() so that - the Parallel Debugger can discover the actual task being invoked. - Details: Here, InnerInvoke is actually being called on the rootTask object while we are actually executing the - childTask. And the debugger needs to discover the childTask, so we pass that down as an argument. - The NoOptimization and NoInlining flags ensure that the childTask pointer is retained, and that this - function appears on the callstack. - - - - - - Performs whatever handling is necessary for an unhandled exception. Normally - this just entails adding the exception to the holder object. - - The exception that went unhandled. - - - - Waits for the to complete execution. - - - The was canceled -or- an exception was thrown during - the execution of the . - - - The has been disposed. - - - - - Waits for the to complete execution. - - - A that represents the number of milliseconds to wait, or a that represents -1 milliseconds to wait indefinitely. - - - true if the completed execution within the allotted time; otherwise, false. - - - The was canceled -or- an exception was thrown during the execution of the . - - - is a negative number other than -1 milliseconds, which represents an - infinite time-out -or- timeout is greater than - . - - - The has been disposed. - - - - - Waits for the to complete execution. - - - A to observe while waiting for the task to complete. - - - The was canceled. - - - The was canceled -or- an exception was thrown during the execution of the . - - - The - has been disposed. - - - - - Waits for the to complete execution. - - - The number of milliseconds to wait, or (-1) to - wait indefinitely. - true if the completed execution within the allotted time; otherwise, - false. - - - is a negative number other than -1, which represents an - infinite time-out. - - - The was canceled -or- an exception was thrown during the execution of the . - - - The - has been disposed. - - - - - Waits for the to complete execution. - - - The number of milliseconds to wait, or (-1) to - wait indefinitely. - - - A to observe while waiting for the task to complete. - - - true if the completed execution within the allotted time; otherwise, false. - - - The was canceled -or- an exception was thrown during the execution of the . - - - The - has been disposed. - - - is a negative number other than -1, which represents an - infinite time-out. - - - The was canceled. - - - - - The core wait function, which is only accesible internally. It's meant to be used in places in TPL code where - the current context is known or cached. - - - - - Cancels the . - - Indiactes whether we should only cancel non-invoked tasks. - For the default scheduler this option will only be serviced through TryDequeue. - For custom schedulers we also attempt an atomic state transition. - true if the task was successfully canceled; otherwise, false. - The - has been disposed. - - - - Sets the task's cancellation acknowledged flag. - - - - - Runs all of the continuations, as appropriate. - - - - - Helper function to determine whether the current task is in the state desired by the - continuation kind under evaluation. Three possibilities exist: the task failed with - an unhandled exception (OnFailed), the task was canceled before running (OnAborted), - or the task completed successfully (OnCompletedSuccessfully). Note that the last - one includes completing due to cancellation. - - The continuation options under evaluation. - True if the continuation should be run given the task's current state. - - - - Creates a continuation that executes when the target completes. - - - An action to run when the completes. When run, the delegate will be - passed the completed task as an argument. - - A new continuation . - - The returned will not be scheduled for execution until the current task has - completed, whether it completes due to running to completion successfully, faulting due to an - unhandled exception, or exiting out early due to being canceled. - - - The argument is null. - - - The has been disposed. - - - - - Creates a continuation that executes when the target completes. - - - An action to run when the completes. When run, the delegate will be - passed the completed task as an argument. - - The that will be assigned to the new continuation task. - A new continuation . - - The returned will not be scheduled for execution until the current task has - completed, whether it completes due to running to completion successfully, faulting due to an - unhandled exception, or exiting out early due to being canceled. - - - The argument is null. - - - The has been disposed. - - The provided CancellationToken - has already been disposed. - - - - - Creates a continuation that executes when the target completes. - - - An action to run when the completes. When run, the delegate will be - passed the completed task as an argument. - - - The to associate with the continuation task and to use for its execution. - - A new continuation . - - The returned will not be scheduled for execution until the current task has - completed, whether it completes due to running to completion successfully, faulting due to an - unhandled exception, or exiting out early due to being canceled. - - - The argument is null. - - - The argument is null. - - - The has been disposed. - - - - - Creates a continuation that executes when the target completes. - - - An action to run when the completes. When run, the delegate will be - passed the completed task as an argument. - - - Options for when the continuation is scheduled and how it behaves. This includes criteria, such - as OnlyOnCanceled, as - well as execution options, such as ExecuteSynchronously. - - A new continuation . - - The returned will not be scheduled for execution until the current task has - completed. If the continuation criteria specified through the parameter are not met, the continuation task will be canceled - instead of scheduled. - - - The argument is null. - - - The argument specifies an invalid value for TaskContinuationOptions. - - - The has been disposed. - - - - - Creates a continuation that executes when the target completes. - - - An action to run when the completes. When run, the delegate will be - passed the completed task as an argument. - - - Options for when the continuation is scheduled and how it behaves. This includes criteria, such - as OnlyOnCanceled, as - well as execution options, such as ExecuteSynchronously. - - The that will be assigned to the new continuation task. - - The to associate with the continuation task and to use for its - execution. - - A new continuation . - - The returned will not be scheduled for execution until the current task has - completed. If the criteria specified through the parameter - are not met, the continuation task will be canceled instead of scheduled. - - - The argument is null. - - - The argument specifies an invalid value for TaskContinuationOptions. - - - The argument is null. - - - The has been disposed. - - The provided CancellationToken - has already been disposed. - - - - - Creates a continuation that executes when the target completes. - - - The type of the result produced by the continuation. - - - A function to run when the completes. When run, the delegate will be - passed the completed task as an argument. - - A new continuation . - - The returned will not be scheduled for execution until the current task has - completed, whether it completes due to running to completion successfully, faulting due to an - unhandled exception, or exiting out early due to being canceled. - - - The argument is null. - - - The has been disposed. - - - - - Creates a continuation that executes when the target completes. - - - The type of the result produced by the continuation. - - - A function to run when the completes. When run, the delegate will be - passed the completed task as an argument. - - The that will be assigned to the new continuation task. - A new continuation . - - The returned will not be scheduled for execution until the current task has - completed, whether it completes due to running to completion successfully, faulting due to an - unhandled exception, or exiting out early due to being canceled. - - - The argument is null. - - - The has been disposed. - - The provided CancellationToken - has already been disposed. - - - - - Creates a continuation that executes when the target completes. - - - The type of the result produced by the continuation. - - - A function to run when the completes. When run, the delegate will be - passed the completed task as an argument. - - - The to associate with the continuation task and to use for its execution. - - A new continuation . - - The returned will not be scheduled for execution until the current task has - completed, whether it completes due to running to completion successfully, faulting due to an - unhandled exception, or exiting out early due to being canceled. - - - The argument is null. - - - The argument is null. - - - The has been disposed. - - - - - Creates a continuation that executes when the target completes. - - - The type of the result produced by the continuation. - - - A function to run when the completes. When run, the delegate will be - passed the completed task as an argument. - - - Options for when the continuation is scheduled and how it behaves. This includes criteria, such - as OnlyOnCanceled, as - well as execution options, such as ExecuteSynchronously. - - A new continuation . - - The returned will not be scheduled for execution until the current task has - completed. If the continuation criteria specified through the parameter are not met, the continuation task will be canceled - instead of scheduled. - - - The argument is null. - - - The argument specifies an invalid value for TaskContinuationOptions. - - - The has been disposed. - - - - - Creates a continuation that executes when the target completes. - - - The type of the result produced by the continuation. - - - A function to run when the completes. When run, the delegate will be - passed the completed task as an argument. - - The that will be assigned to the new continuation task. - - Options for when the continuation is scheduled and how it behaves. This includes criteria, such - as OnlyOnCanceled, as - well as execution options, such as ExecuteSynchronously. - - - The to associate with the continuation task and to use for its - execution. - - A new continuation . - - The returned will not be scheduled for execution until the current task has - completed. If the criteria specified through the parameter - are not met, the continuation task will be canceled instead of scheduled. - - - The argument is null. - - - The argument specifies an invalid value for TaskContinuationOptions. - - - The argument is null. - - - The has been disposed. - - The provided CancellationToken - has already been disposed. - - - - - Converts TaskContinuationOptions to TaskCreationOptions, and also does - some validity checking along the way. - - Incoming TaskContinuationOptions - Outgoing TaskCreationOptions - Outgoing InternalTaskOptions - - - - Registers the continuation and possibly runs it (if the task is already finished). - - The continuation task itself. - TaskScheduler with which to associate continuation task. - Restrictions on when the continuation becomes active. - - - - Waits for all of the provided objects to complete execution. - - - An array of instances on which to wait. - - - The argument is null. - - - The argument contains a null element. - - - At least one of the instances was canceled -or- an exception was thrown during - the execution of at least one of the instances. - - - The has been disposed. - - - - - Waits for all of the provided objects to complete execution. - - - true if all of the instances completed execution within the allotted time; - otherwise, false. - - - An array of instances on which to wait. - - - A that represents the number of milliseconds to wait, or a that represents -1 milliseconds to wait indefinitely. - - - The argument is null. - - - The argument contains a null element. - - - At least one of the instances was canceled -or- an exception was thrown during - the execution of at least one of the instances. - - - is a negative number other than -1 milliseconds, which represents an - infinite time-out -or- timeout is greater than - . - - - The has been disposed. - - - - - Waits for all of the provided objects to complete execution. - - - true if all of the instances completed execution within the allotted time; - otherwise, false. - - - The number of milliseconds to wait, or (-1) to - wait indefinitely. - An array of instances on which to wait. - - - The argument is null. - - - The argument contains a null element. - - - At least one of the instances was canceled -or- an exception was thrown during - the execution of at least one of the instances. - - - The has been disposed. - - - is a negative number other than -1, which represents an - infinite time-out. - - - - - Waits for all of the provided objects to complete execution. - - - true if all of the instances completed execution within the allotted time; - otherwise, false. - - - An array of instances on which to wait. - - - A to observe while waiting for the tasks to complete. - - - The argument is null. - - - The argument contains a null element. - - - At least one of the instances was canceled -or- an exception was thrown during - the execution of at least one of the instances. - - - The was canceled. - - - The has been disposed. - - - - - Waits for all of the provided objects to complete execution. - - - true if all of the instances completed execution within the allotted time; - otherwise, false. - - - An array of instances on which to wait. - - - The number of milliseconds to wait, or (-1) to - wait indefinitely. - - - A to observe while waiting for the tasks to complete. - - - The argument is null. - - - The argument contains a null element. - - - At least one of the instances was canceled -or- an exception was thrown during - the execution of at least one of the instances. - - - The has been disposed. - - - is a negative number other than -1, which represents an - infinite time-out. - - - The was canceled. - - - - - Waits for a set of handles in a STA-aware way. In other words, it will wait for each - of the events individually if we're on a STA thread, because MsgWaitForMultipleObjectsEx - can't do a true wait-all due to its hidden message queue event. This is not atomic, - of course, but we only wait on one-way (MRE) events anyway so this is OK. - - An array of wait handles to wait on. - The timeout to use during waits. - The cancellationToken that enables a wait to be canceled. - True if all waits succeeded, false if a timeout occurred. - - - - Internal WaitAll implementation which is meant to be used with small number of tasks, - optimized for Parallel.Invoke and other structured primitives. - - - - - This internal function is only meant to be called by WaitAll() - If the completed task is canceled or it has other exceptions, here we will add those - into the passed in exception list (which will be lazily initialized here). - - - - - Waits for any of the provided objects to complete execution. - - - An array of instances on which to wait. - - The index of the completed task in the array argument. - - The argument is null. - - - The argument contains a null element. - - - The has been disposed. - - - - - Waits for any of the provided objects to complete execution. - - - An array of instances on which to wait. - - - A that represents the number of milliseconds to wait, or a that represents -1 milliseconds to wait indefinitely. - - - The index of the completed task in the array argument, or -1 if the - timeout occurred. - - - The argument is null. - - - The argument contains a null element. - - - The has been disposed. - - - is a negative number other than -1 milliseconds, which represents an - infinite time-out -or- timeout is greater than - . - - - - - Waits for any of the provided objects to complete execution. - - - An array of instances on which to wait. - - - A to observe while waiting for a task to complete. - - - The index of the completed task in the array argument. - - - The argument is null. - - - The argument contains a null element. - - - The has been disposed. - - - The was canceled. - - - - - Waits for any of the provided objects to complete execution. - - - An array of instances on which to wait. - - - The number of milliseconds to wait, or (-1) to - wait indefinitely. - - - The index of the completed task in the array argument, or -1 if the - timeout occurred. - - - The argument is null. - - - The argument contains a null element. - - - The has been disposed. - - - is a negative number other than -1, which represents an - infinite time-out. - - - - - Waits for any of the provided objects to complete execution. - - - An array of instances on which to wait. - - - The number of milliseconds to wait, or (-1) to - wait indefinitely. - - - A to observe while waiting for a task to complete. - - - The index of the completed task in the array argument, or -1 if the - timeout occurred. - - - The argument is null. - - - The argument contains a null element. - - - The has been disposed. - - - is a negative number other than -1, which represents an - infinite time-out. - - - The was canceled. - - - - - Gets a unique ID for this Task instance. - - - Task IDs are assigned on-demand and do not necessarily represent the order in the which Task - instances were created. - - - - - Returns the unique ID of the currently executing Task. - - - - - Gets the Task instance currently executing, or - null if none exists. - - - - - Gets the StackGuard object assigned to the current thread. - - - - - Gets the Exception that caused the Task to end prematurely. If the Task completed successfully or has not yet thrown any - exceptions, this will return null. - - - Tasks that throw unhandled exceptions store the resulting exception and propagate it wrapped in a - in calls to Wait - or in accesses to the property. Any exceptions not observed by the time - the Task instance is garbage collected will be propagated on the finalizer thread. - - - The Task - has been disposed. - - - - - Gets the TaskStatus of this Task. - - - - - Gets whether this Task instance has completed - execution due to being canceled. - - - A Task will complete in Canceled state either if its CancellationToken - was marked for cancellation before the task started executing, or if the task acknowledged the cancellation request on - its already signaled CancellationToken by throwing an - OperationCanceledException that bears the same - CancellationToken. - - - - - Returns true if this task has a cancellation token and it was signaled. - To be used internally in execute entry codepaths. - - - - - This internal property provides access to the CancellationToken that was set on the task - when it was constructed. - - - - - Gets whether this threw an OperationCanceledException while its CancellationToken was signaled. - - - - - Gets whether this Task has completed. - - - will return true when the Task is in one of the three - final states: RanToCompletion, - Faulted, or - Canceled. - - - - - Checks whether this task has been disposed. - - - - - Gets the TaskCreationOptions used - to create this task. - - - - - Gets a that can be used to wait for the task to - complete. - - - Using the wait functionality provided by - should be preferred over using for similar - functionality. - - - The has been disposed. - - - - - Gets the state object supplied when the Task was created, - or null if none was supplied. - - - - - Gets an indication of whether the asynchronous operation completed synchronously. - - true if the asynchronous operation completed synchronously; otherwise, false. - - - - Provides access to the TaskScheduler responsible for executing this Task. - - - - - Provides access to factory methods for creating and instances. - - - The factory returned from is a default instance - of , as would result from using - the default constructor on TaskFactory. - - - - - Provides an event that can be used to wait for completion. - Only called by Wait*(), which means that we really do need to instantiate a completion event. - - - - - Determines whether this is the root task of a self replicating group. - - - - - Determines whether the task is a replica itself. - - - - - The property formerly known as IsFaulted. - - - - - Gets whether the completed due to an unhandled exception. - - - If is true, the Task's will be equal to - TaskStatus.Faulted, and its - property will be non-null. - - - - - Checks whether the TASK_STATE_EXCEPTIONOBSERVEDBYPARENT status flag is set, - This will only be used by the implicit wait to prevent double throws - - - - - - Checks whether the body was ever invoked. Used by task scheduler code to verify custom schedulers actually ran the task. - - - - - A structure to hold continuation information. - - - - - Constructs a new continuation structure. - - The task to be activated. - The continuation options. - The scheduler to use for the continuation. - - - - Invokes the continuation for the target completion task. - - The completed task. - Whether the continuation can be inlined. - - - - Initializes a new with the specified function. - - - The delegate that represents the code to execute in the task. When the function has completed, - the task's property will be set to return the result value of the function. - - - The argument is null. - - - - - Initializes a new with the specified function. - - - The delegate that represents the code to execute in the task. When the function has completed, - the task's property will be set to return the result value of the function. - - The to be assigned to this task. - - The argument is null. - - The provided CancellationToken - has already been disposed. - - - - - Initializes a new with the specified function and creation options. - - - The delegate that represents the code to execute in the task. When the function has completed, - the task's property will be set to return the result value of the function. - - - The TaskCreationOptions used to - customize the task's behavior. - - - The argument is null. - - - The argument specifies an invalid value for . - - - - - Initializes a new with the specified function and creation options. - - - The delegate that represents the code to execute in the task. When the function has completed, - the task's property will be set to return the result value of the function. - - The that will be assigned to the new task. - - The TaskCreationOptions used to - customize the task's behavior. - - - The argument is null. - - - The argument specifies an invalid value for . - - The provided CancellationToken - has already been disposed. - - - - - Initializes a new with the specified function and state. - - - The delegate that represents the code to execute in the task. When the function has completed, - the task's property will be set to return the result value of the function. - - An object representing data to be used by the action. - - The argument is null. - - - - - Initializes a new with the specified action, state, and options. - - - The delegate that represents the code to execute in the task. When the function has completed, - the task's property will be set to return the result value of the function. - - An object representing data to be used by the function. - The to be assigned to the new task. - - The argument is null. - - The provided CancellationToken - has already been disposed. - - - - - Initializes a new with the specified action, state, and options. - - - The delegate that represents the code to execute in the task. When the function has completed, - the task's property will be set to return the result value of the function. - - An object representing data to be used by the function. - - The TaskCreationOptions used to - customize the task's behavior. - - - The argument is null. - - - The argument specifies an invalid value for . - - - - - Initializes a new with the specified action, state, and options. - - - The delegate that represents the code to execute in the task. When the function has completed, - the task's property will be set to return the result value of the function. - - An object representing data to be used by the function. - The to be assigned to the new task. - - The TaskCreationOptions used to - customize the task's behavior. - - - The argument is null. - - - The argument specifies an invalid value for . - - The provided CancellationToken - has already been disposed. - - - - - Creates a new future object. - - The parent task for this future. - A function that yields the future value. - The task scheduler which will be used to execute the future. - The CancellationToken for the task. - Options to control the future's behavior. - Internal options to control the future's behavior. - The argument specifies - a SelfReplicating , which is illegal."/>. - - - - Creates a new future object. - - The parent task for this future. - An object containing data to be used by the action; may be null. - A function that yields the future value. - The CancellationToken for the task. - The task scheduler which will be used to execute the future. - Options to control the future's behavior. - Internal options to control the future's behavior. - The argument specifies - a SelfReplicating , which is illegal."/>. - - - - Evaluates the value selector of the Task which is passed in as an object and stores the result. - - - - - Creates a continuation that executes when the target completes. - - - An action to run when the completes. When run, the delegate will be - passed the completed task as an argument. - - A new continuation . - - The returned will not be scheduled for execution until the current task has - completed, whether it completes due to running to completion successfully, faulting due to an - unhandled exception, or exiting out early due to being canceled. - - - The argument is null. - - - The has been disposed. - - - - - Creates a continuation that executes when the target completes. - - - An action to run when the completes. When run, the delegate will be - passed the completed task as an argument. - - The that will be assigned to the new continuation task. - A new continuation . - - The returned will not be scheduled for execution until the current task has - completed, whether it completes due to running to completion successfully, faulting due to an - unhandled exception, or exiting out early due to being canceled. - - - The argument is null. - - - The has been disposed. - - The provided CancellationToken - has already been disposed. - - - - - Creates a continuation that executes when the target completes. - - - An action to run when the completes. When run, the delegate will be - passed the completed task as an argument. - - - The to associate with the continuation task and to use for its execution. - - A new continuation . - - The returned will not be scheduled for execution until the current task has - completed, whether it completes due to running to completion successfully, faulting due to an - unhandled exception, or exiting out early due to being canceled. - - - The argument is null. - - - The argument is null. - - - The has been disposed. - - - - - Creates a continuation that executes when the target completes. - - - An action to run when the completes. When run, the delegate will be - passed the completed task as an argument. - - - Options for when the continuation is scheduled and how it behaves. This includes criteria, such - as OnlyOnCanceled, as - well as execution options, such as ExecuteSynchronously. - - A new continuation . - - The returned will not be scheduled for execution until the current task has - completed. If the continuation criteria specified through the parameter are not met, the continuation task will be canceled - instead of scheduled. - - - The argument is null. - - - The argument specifies an invalid value for TaskContinuationOptions. - - - The has been disposed. - - - - - Creates a continuation that executes when the target completes. - - - An action to run when the completes. When run, the delegate will be - passed the completed task as an argument. - - The that will be assigned to the new continuation task. - - Options for when the continuation is scheduled and how it behaves. This includes criteria, such - as OnlyOnCanceled, as - well as execution options, such as ExecuteSynchronously. - - - The to associate with the continuation task and to use for its - execution. - - A new continuation . - - The returned will not be scheduled for execution until the current task has - completed. If the criteria specified through the parameter - are not met, the continuation task will be canceled instead of scheduled. - - - The argument is null. - - - The argument specifies an invalid value for TaskContinuationOptions. - - - The argument is null. - - - The has been disposed. - - The provided CancellationToken - has already been disposed. - - - - - Creates a continuation that executes when the target completes. - - - The type of the result produced by the continuation. - - - A function to run when the completes. When run, the delegate will be - passed the completed task as an argument. - - A new continuation . - - The returned will not be scheduled for execution until the current - task has completed, whether it completes due to running to completion successfully, faulting due - to an unhandled exception, or exiting out early due to being canceled. - - - The argument is null. - - - The has been disposed. - - - - - Creates a continuation that executes when the target completes. - - - The type of the result produced by the continuation. - - - A function to run when the completes. When run, the delegate will be - passed the completed task as an argument. - - The that will be assigned to the new task. - A new continuation . - - The returned will not be scheduled for execution until the current - task has completed, whether it completes due to running to completion successfully, faulting due - to an unhandled exception, or exiting out early due to being canceled. - - - The argument is null. - - - The has been disposed. - - The provided CancellationToken - has already been disposed. - - - - - Creates a continuation that executes when the target completes. - - - The type of the result produced by the continuation. - - - A function to run when the completes. When run, the delegate will be - passed the completed task as an argument. - - - The to associate with the continuation task and to use for its execution. - - A new continuation . - - The returned will not be scheduled for execution until the current task has - completed, whether it completes due to running to completion successfully, faulting due to an - unhandled exception, or exiting out early due to being canceled. - - - The argument is null. - - - The argument is null. - - - The has been disposed. - - - - - Creates a continuation that executes when the target completes. - - - The type of the result produced by the continuation. - - - A function to run when the completes. When run, the delegate will be - passed the completed task as an argument. - - - Options for when the continuation is scheduled and how it behaves. This includes criteria, such - as OnlyOnCanceled, as - well as execution options, such as ExecuteSynchronously. - - A new continuation . - - - The returned will not be scheduled for execution until the current - task has completed, whether it completes due to running to completion successfully, faulting due - to an unhandled exception, or exiting out early due to being canceled. - - - The , when executed, should return a . This task's completion state will be transferred to the task returned - from the ContinueWith call. - - - - The argument is null. - - - The argument specifies an invalid value for TaskContinuationOptions. - - - The has been disposed. - - - - - Creates a continuation that executes when the target completes. - - - The type of the result produced by the continuation. - - - A function to run when the completes. When run, the delegate will be passed as - an argument this completed task. - - The that will be assigned to the new task. - - Options for when the continuation is scheduled and how it behaves. This includes criteria, such - as OnlyOnCanceled, as - well as execution options, such as ExecuteSynchronously. - - - The to associate with the continuation task and to use for its - execution. - - A new continuation . - - - The returned will not be scheduled for execution until the current task has - completed, whether it completes due to running to completion successfully, faulting due to an - unhandled exception, or exiting out early due to being canceled. - - - The , when executed, should return a . - This task's completion state will be transferred to the task returned from the - ContinueWith call. - - - - The argument is null. - - - The argument specifies an invalid value for TaskContinuationOptions. - - - The argument is null. - - - The has been disposed. - - The provided CancellationToken - has already been disposed. - - - - - Gets the result value of this . - - - The get accessor for this property ensures that the asynchronous operation is complete before - returning. Once the result of the computation is available, it is stored and will be returned - immediately on later calls to . - - - - - Provides access to factory methods for creating instances. - - - The factory returned from is a default instance - of , as would result from using - the default constructor on the factory type. - - - - - Provides support for creating and scheduling - Task{TResult} objects. - - The type of the results that are available though - the Task{TResult} objects that are associated with - the methods in this class. - - - There are many common patterns for which tasks are relevant. The - class encodes some of these patterns into methods that pick up default settings, which are - configurable through its constructors. - - - A default instance of is available through the - Task{TResult}.Factory property. - - - - - - Initializes a instance with the default configuration. - - - This constructor creates a instance with a default configuration. The - property is initialized to - TaskCreationOptions.None, the - property is initialized to TaskContinuationOptions.None, - and the TaskScheduler property is - initialized to the current scheduler (see TaskScheduler.Current). - - - - - Initializes a instance with the default configuration. - - The default that will be assigned - to tasks created by this unless another CancellationToken is explicitly specified - while calling the factory methods. - - This constructor creates a instance with a default configuration. The - property is initialized to - TaskCreationOptions.None, the - property is initialized to TaskContinuationOptions.None, - and the TaskScheduler property is - initialized to the current scheduler (see TaskScheduler.Current). - - - - - Initializes a instance with the specified configuration. - - - The - TaskScheduler to use to schedule any tasks created with this TaskFactory{TResult}. A null value - indicates that the current TaskScheduler should be used. - - - With this constructor, the - property is initialized to - TaskCreationOptions.None, the - property is initialized to TaskContinuationOptions.None, - and the TaskScheduler property is - initialized to , unless it's null, in which case the property is - initialized to the current scheduler (see TaskScheduler.Current). - - - - - Initializes a instance with the specified configuration. - - - The default - TaskCreationOptions to use when creating tasks with this TaskFactory{TResult}. - - - The default - TaskContinuationOptions to use when creating continuation tasks with this TaskFactory{TResult}. - - - The exception that is thrown when the - argument or the - argument specifies an invalid value. - - - With this constructor, the - property is initialized to , - the - property is initialized to , and the TaskScheduler property is initialized to the - current scheduler (see TaskScheduler.Current). - - - - - Initializes a instance with the specified configuration. - - The default that will be assigned - to tasks created by this unless another CancellationToken is explicitly specified - while calling the factory methods. - - The default - TaskCreationOptions to use when creating tasks with this TaskFactory{TResult}. - - - The default - TaskContinuationOptions to use when creating continuation tasks with this TaskFactory{TResult}. - - - The default - TaskScheduler to use to schedule any Tasks created with this TaskFactory{TResult}. A null value - indicates that TaskScheduler.Current should be used. - - - The exception that is thrown when the - argument or the - argumentspecifies an invalid value. - - - With this constructor, the - property is initialized to , - the - property is initialized to , and the TaskScheduler property is initialized to - , unless it's null, in which case the property is initialized to the - current scheduler (see TaskScheduler.Current). - - - - - Creates and starts a . - - A function delegate that returns the future result to be available through - the . - The started . - The exception that is thrown when the - argument is null. - - Calling StartNew is functionally equivalent to creating a using one - of its constructors and then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates and starts a . - - A function delegate that returns the future result to be available through - the . - The that will be assigned to the new task. - The started . - The exception that is thrown when the - argument is null. - The provided CancellationToken - has already been disposed. - - - Calling StartNew is functionally equivalent to creating a using one - of its constructors and then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates and starts a . - - A function delegate that returns the future result to be available through - the . - A TaskCreationOptions value that controls the behavior of the - created - . - The started . - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - - Calling StartNew is functionally equivalent to creating a using one - of its constructors and then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates and starts a . - - A function delegate that returns the future result to be available through - the . - A TaskCreationOptions value that controls the behavior of the - created - . - The that will be assigned to the new task. - The TaskScheduler - that is used to schedule the created - Task{TResult}. - The started . - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - The provided CancellationToken - has already been disposed. - - - Calling StartNew is functionally equivalent to creating a using one - of its constructors and then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates and starts a . - - A function delegate that returns the future result to be available through - the . - An object containing data to be used by the - delegate. - The started . - The exception that is thrown when the - argument is null. - - Calling StartNew is functionally equivalent to creating a using one - of its constructors and then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates and starts a . - - A function delegate that returns the future result to be available through - the . - An object containing data to be used by the - delegate. - The that will be assigned to the new task. - The started . - The exception that is thrown when the - argument is null. - The provided CancellationToken - has already been disposed. - - - Calling StartNew is functionally equivalent to creating a using one - of its constructors and then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates and starts a . - - A function delegate that returns the future result to be available through - the . - An object containing data to be used by the - delegate. - A TaskCreationOptions value that controls the behavior of the - created - . - The started . - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - - Calling StartNew is functionally equivalent to creating a using one - of its constructors and then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates and starts a . - - A function delegate that returns the future result to be available through - the . - An object containing data to be used by the - delegate. - The that will be assigned to the new task. - A TaskCreationOptions value that controls the behavior of the - created - . - The TaskScheduler - that is used to schedule the created - Task{TResult}. - The started . - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - The provided CancellationToken - has already been disposed. - - - Calling StartNew is functionally equivalent to creating a using one - of its constructors and then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates a Task that executes an end - method function when a specified IAsyncResult completes. - - The IAsyncResult whose completion should trigger the processing of the - . - The function delegate that processes the completed . - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - A Task that represents the - asynchronous operation. - - - - Creates a Task that executes an end - method function when a specified IAsyncResult completes. - - The IAsyncResult whose completion should trigger the processing of the - . - The function delegate that processes the completed . - The TaskCreationOptions value that controls the behavior of the - created Task. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - A Task that represents the - asynchronous operation. - - - - Creates a Task that executes an end - method function when a specified IAsyncResult completes. - - The IAsyncResult whose completion should trigger the processing of the - . - The function delegate that processes the completed . - The TaskScheduler - that is used to schedule the task that executes the end method. - The TaskCreationOptions value that controls the behavior of the - created Task. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - A Task that represents the - asynchronous operation. - - - - Creates a Task that represents a pair of - begin and end methods that conform to the Asynchronous Programming Model pattern. - - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The created Task that - represents the asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that represents a pair of - begin and end methods that conform to the Asynchronous Programming Model pattern. - - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - The TaskCreationOptions value that controls the behavior of the - created Task. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - The created Task that - represents the asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that represents a pair of - begin and end methods that conform to the Asynchronous Programming Model pattern. - - The type of the first argument passed to the delegate. - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - The first argument passed to the - delegate. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The created Task that - represents the asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that represents a pair of - begin and end methods that conform to the Asynchronous Programming Model pattern. - - The type of the first argument passed to the delegate. - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - The first argument passed to the - delegate. - The TaskCreationOptions value that controls the behavior of the - created Task. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - The created Task that - represents the asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that represents a pair of - begin and end methods that conform to the Asynchronous Programming Model pattern. - - The type of the first argument passed to the delegate. - The type of the second argument passed to - delegate. - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - The first argument passed to the - delegate. - The second argument passed to the - delegate. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The created Task that - represents the asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that represents a pair of - begin and end methods that conform to the Asynchronous Programming Model pattern. - - The type of the first argument passed to the delegate. - The type of the second argument passed to - delegate. - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - The first argument passed to the - delegate. - The second argument passed to the - delegate. - The TaskCreationOptions value that controls the behavior of the - created Task. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - The created Task that - represents the asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that represents a pair of - begin and end methods that conform to the Asynchronous Programming Model pattern. - - The type of the first argument passed to the delegate. - The type of the second argument passed to - delegate. - The type of the third argument passed to - delegate. - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - The first argument passed to the - delegate. - The second argument passed to the - delegate. - The third argument passed to the - delegate. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The created Task that - represents the asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that represents a pair of - begin and end methods that conform to the Asynchronous Programming Model pattern. - - The type of the first argument passed to the delegate. - The type of the second argument passed to - delegate. - The type of the third argument passed to - delegate. - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - The first argument passed to the - delegate. - The second argument passed to the - delegate. - The third argument passed to the - delegate. - The TaskCreationOptions value that controls the behavior of the - created Task. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - The created Task that - represents the asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The array of tasks from which to continue. - The function delegate to execute when all tasks in - the array have completed. - The new continuation Task. - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The array of tasks from which to continue. - The function delegate to execute when all tasks in - the array have completed. - The CancellationToken - that will be assigned to the new continuation task. - The new continuation Task. - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The array of tasks from which to continue. - The function delegate to execute when all tasks in the array have completed. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The new continuation Task. - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAll. - - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The array of tasks from which to continue. - The function delegate to execute when all tasks in the array have completed. - The CancellationToken - that will be assigned to the new continuation task. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The TaskScheduler - that is used to schedule the created continuation Task. - The new continuation Task. - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAll. - - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The type of the result of the antecedent . - The array of tasks from which to continue. - The function delegate to execute when all tasks in the - array have completed. - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The type of the result of the antecedent . - The array of tasks from which to continue. - The function delegate to execute when all tasks in the - array have completed. - The CancellationToken - that will be assigned to the new continuation task. - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The type of the result of the antecedent . - The array of tasks from which to continue. - The function delegate to execute when all tasks in the - array have completed. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAll. - - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The type of the result of the antecedent . - The array of tasks from which to continue. - The function delegate to execute when all tasks in the - array have completed. - The CancellationToken - that will be assigned to the new continuation task. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The TaskScheduler - that is used to schedule the created continuation . - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAll. - - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The array of tasks from which to continue when one task completes. - The function delegate to execute when one task in the array completes. - The new continuation Task. - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The array of tasks from which to continue when one task completes. - The function delegate to execute when one task in the array completes. - The CancellationToken - that will be assigned to the new continuation task. - The new continuation Task. - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The array of tasks from which to continue when one task completes. - The function delegate to execute when one task in the array completes. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The new continuation Task. - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAny. - - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The array of tasks from which to continue when one task completes. - The function delegate to execute when one task in the array completes. - The CancellationToken - that will be assigned to the new continuation task. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The TaskScheduler - that is used to schedule the created continuation Task. - The new continuation Task. - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAny. - - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The type of the result of the antecedent . - The array of tasks from which to continue when one task completes. - The function delegate to execute when one task in the - array completes. - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The type of the result of the antecedent . - The array of tasks from which to continue when one task completes. - The function delegate to execute when one task in the - array completes. - The CancellationToken - that will be assigned to the new continuation task. - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The type of the result of the antecedent . - The array of tasks from which to continue when one task completes. - The function delegate to execute when one task in the - array completes. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAny. - - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The type of the result of the antecedent . - The array of tasks from which to continue when one task completes. - The function delegate to execute when one task in the - array completes. - The CancellationToken - that will be assigned to the new continuation task. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The TaskScheduler - that is used to schedule the created continuation . - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAny. - - - - - Gets the default CancellationToken of this - TaskFactory. - - - This property returns the default that will be assigned to all - tasks created by this factory unless another CancellationToken value is explicitly specified - during the call to the factory methods. - - - - - Gets the TaskScheduler of this - TaskFactory{TResult}. - - - This property returns the default scheduler for this factory. It will be used to schedule all - tasks unless another scheduler is explicitly specified during calls to this factory's methods. - If null, TaskScheduler.Current - will be used. - - - - - Gets the TaskCreationOptions - value of this TaskFactory{TResult}. - - - This property returns the default creation options for this factory. They will be used to create all - tasks unless other options are explicitly specified during calls to this factory's methods. - - - - - Gets the TaskContinuationOptions - value of this TaskFactory{TResult}. - - - This property returns the default continuation options for this factory. They will be used to create - all continuation tasks unless other options are explicitly specified during calls to this factory's methods. - - - - - Represents the current stage in the lifecycle of a . - - - - - The task has been initialized but has not yet been scheduled. - - - - - The task is waiting to be activated and scheduled internally by the .NET Framework infrastructure. - - - - - The task has been scheduled for execution but has not yet begun executing. - - - - - The task is running but has not yet completed. - - - - - The task has finished executing and is implicitly waiting for - attached child tasks to complete. - - - - - The task completed execution successfully. - - - - - The task acknowledged cancellation by throwing an OperationCanceledException with its own CancellationToken - while the token was in signaled state, or the task's CancellationToken was already signaled before the - task started executing. - - - - - The task completed due to an unhandled exception. - - - - - In some cases a replica will want to quit prematurely (ie. before finishing a chunk of work it may have grabbed) - yet they will need the next replica to pick things up from where they left. This API is used to save such state. - - Calling it is also the only way to record a premature exit. - - - - - - Specifies flags that control optional behavior for the creation and execution of tasks. - - - - - Specifies that the default behavior should be used. - - - - - A hint to a TaskScheduler to schedule a - task in as fair a manner as possible, meaning that tasks scheduled sooner will be more likely to - be run sooner, and tasks scheduled later will be more likely to be run later. - - - - - Specifies that a task will be a long-running, course-grained operation. It provides a hint to the - TaskScheduler that oversubscription may be - warranted. - - - - - Specifies that a task is attached to a parent in the task hierarchy. - - - - - Task creation flags which are only used internally. - - - - Specifies "No internal task options" - - - Used to filter out internal vs. public task creation options. - - - Specifies that the task will be queued by the runtime before handing it over to the user. - This flag will be used to skip the cancellationtoken registration step, which is only meant for unstarted tasks. - - - - Specifies flags that control optional behavior for the creation and execution of continuation tasks. - - - - - Default = "Continue on any, no task options, run asynchronously" - Specifies that the default behavior should be used. Continuations, by default, will - be scheduled when the antecedent task completes, regardless of the task's final TaskStatus. - - - - - A hint to a TaskScheduler to schedule a - task in as fair a manner as possible, meaning that tasks scheduled sooner will be more likely to - be run sooner, and tasks scheduled later will be more likely to be run later. - - - - - Specifies that a task will be a long-running, course-grained operation. It provides - a hint to the TaskScheduler that - oversubscription may be warranted. - - - - - Specifies that a task is attached to a parent in the task hierarchy. - - - - - Specifies that the continuation task should not be scheduled if its antecedent ran to completion. - This option is not valid for multi-task continuations. - - - - - Specifies that the continuation task should not be scheduled if its antecedent threw an unhandled - exception. This option is not valid for multi-task continuations. - - - - - Specifies that the continuation task should not be scheduled if its antecedent was canceled. This - option is not valid for multi-task continuations. - - - - - Specifies that the continuation task should be scheduled only if its antecedent ran to - completion. This option is not valid for multi-task continuations. - - - - - Specifies that the continuation task should be scheduled only if its antecedent threw an - unhandled exception. This option is not valid for multi-task continuations. - - - - - Specifies that the continuation task should be scheduled only if its antecedent was canceled. - This option is not valid for multi-task continuations. - - - - - Specifies that the continuation task should be executed synchronously. With this option - specified, the continuation will be run on the same thread that causes the antecedent task to - transition into its final state. If the antecedent is already complete when the continuation is - created, the continuation will run on the thread creating the continuation. Only very - short-running continuations should be executed synchronously. - - - - - Internal helper class to keep track of stack depth and decide whether we should inline or not. - - - - - This method needs to be called before attempting inline execution on the current thread. - If false is returned, it means we are too close to the end of the stack and should give up inlining. - Each call to TryBeginInliningScope() that returns true must be matched with a - call to EndInliningScope() regardless of whether inlining actually took place. - - - - - This needs to be called once for each previous successful TryBeginInliningScope() call after - inlining related logic runs. - - - - - Represents an exception used to communicate task cancellation. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the - class with a specified error message. - - The error message that explains the reason for the exception. - - - - Initializes a new instance of the - class with a specified error message and a reference to the inner exception that is the cause of - this exception. - - The error message that explains the reason for the exception. - The exception that is the cause of the current exception. - - - - Initializes a new instance of the class - with a reference to the that has been canceled. - - A task that has been canceled. - - - - Initializes a new instance of the - class with serialized data. - - The that holds the serialized object data about the exception being thrown. - The that contains contextual information about the source or destination. - - - - Gets the task associated with this exception. - - - It is permissible for no Task to be associated with a - , in which case - this property will return null. - - - - - An exception holder manages a list of exceptions for one particular task. - It offers the ability to aggregate, but more importantly, also offers intrinsic - support for propagating unhandled exceptions that are never observed. It does - this by aggregating and throwing if the holder is ever GC'd without the holder's - contents ever having been requested (e.g. by a Task.Wait, Task.get_Exception, etc). - - - - - Creates a new holder; it will be registered for finalization. - - The task this holder belongs to. - - - - A finalizer that repropagates unhandled exceptions. - - - - - Add an exception to the internal list. This will ensure the holder is - in the proper state (handled/unhandled) depending on the list's contents. - - An exception object (either an Exception or an - IEnumerable{Exception}) to add to the list. - - - - A private helper method that ensures the holder is considered - unhandled, i.e. it is registered for finalization. - - - - - A private helper method that ensures the holder is considered - handled, i.e. it is not registered for finalization. - - Whether this is called from the finalizer thread. - - - - Allocates a new aggregate exception and adds the contents of the list to - it. By calling this method, the holder assumes exceptions to have been - "observed", such that the finalization check will be subsequently skipped. - - Whether this is being called from a finalizer. - An extra exception to be included (optionally). - The aggregate exception to throw. - - - - Provides support for creating and scheduling - Tasks. - - - - There are many common patterns for which tasks are relevant. The - class encodes some of these patterns into methods that pick up default settings, which are - configurable through its constructors. - - - A default instance of is available through the - Task.Factory property. - - - - - - Initializes a instance with the default configuration. - - - This constructor creates a instance with a default configuration. The - property is initialized to - TaskCreationOptions.None, the - property is initialized to TaskContinuationOptions.None, - and the TaskScheduler property is - initialized to the current scheduler (see TaskScheduler.Current). - - - - - Initializes a instance with the specified configuration. - - The default that will be assigned - to tasks created by this unless another CancellationToken is explicitly specified - while calling the factory methods. - - This constructor creates a instance with a default configuration. The - property is initialized to - TaskCreationOptions.None, the - property is initialized to TaskContinuationOptions.None, - and the TaskScheduler property is - initialized to the current scheduler (see TaskScheduler.Current). - - - - - Initializes a instance with the specified configuration. - - - The - TaskScheduler to use to schedule any tasks created with this TaskFactory. A null value - indicates that the current TaskScheduler should be used. - - - With this constructor, the - property is initialized to - TaskCreationOptions.None, the - property is initialized to TaskContinuationOptions.None, - and the TaskScheduler property is - initialized to , unless it's null, in which case the property is - initialized to the current scheduler (see TaskScheduler.Current). - - - - - Initializes a instance with the specified configuration. - - - The default - TaskCreationOptions to use when creating tasks with this TaskFactory. - - - The default - TaskContinuationOptions to use when creating continuation tasks with this TaskFactory. - - - The exception that is thrown when the - argument or the - argument specifies an invalid value. - - - With this constructor, the - property is initialized to , - the - property is initialized to , and the TaskScheduler property is initialized to the - current scheduler (see TaskScheduler.Current). - - - - - Initializes a instance with the specified configuration. - - The default that will be assigned - to tasks created by this unless another CancellationToken is explicitly specified - while calling the factory methods. - - The default - TaskCreationOptions to use when creating tasks with this TaskFactory. - - - The default - TaskContinuationOptions to use when creating continuation tasks with this TaskFactory. - - - The default - TaskScheduler to use to schedule any Tasks created with this TaskFactory. A null value - indicates that TaskScheduler.Current should be used. - - - The exception that is thrown when the - argument or the - argumentspecifies an invalid value. - - - With this constructor, the - property is initialized to , - the - property is initialized to , and the TaskScheduler property is initialized to - , unless it's null, in which case the property is initialized to the - current scheduler (see TaskScheduler.Current). - - - - - Creates and starts a Task. - - The action delegate to execute asynchronously. - The started Task. - The exception that is thrown when the - argument is null. - - Calling StartNew is functionally equivalent to creating a Task using one of its constructors - and then calling - Start to schedule it for execution. However, - unless creation and scheduling must be separated, StartNew is the recommended - approach for both simplicity and performance. - - - - - Creates and starts a Task. - - The action delegate to execute asynchronously. - The that will be assigned to the new task. - The started Task. - The exception that is thrown when the - argument is null. - The provided CancellationToken - has already been disposed. - - - Calling StartNew is functionally equivalent to creating a Task using one of its constructors - and then calling - Start to schedule it for execution. However, - unless creation and scheduling must be separated, StartNew is the recommended - approach for both simplicity and performance. - - - - - Creates and starts a Task. - - The action delegate to execute asynchronously. - A TaskCreationOptions value that controls the behavior of the - created - Task. - The started Task. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - - Calling StartNew is functionally equivalent to creating a Task using one of its constructors and - then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates and starts a Task. - - The action delegate to execute asynchronously. - The that will be assigned to the new - A TaskCreationOptions value that controls the behavior of the - created - Task. - The TaskScheduler - that is used to schedule the created Task. - The started Task. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - The provided CancellationToken - has already been disposed. - - - Calling StartNew is functionally equivalent to creating a Task using one of its constructors and - then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates and starts a Task. - - The action delegate to execute asynchronously. - An object containing data to be used by the - delegate. - The started Task. - The exception that is thrown when the - argument is null. - - Calling StartNew is functionally equivalent to creating a Task using one of its constructors and - then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates and starts a Task. - - The action delegate to execute asynchronously. - An object containing data to be used by the - delegate. - The that will be assigned to the new - The started Task. - The exception that is thrown when the - argument is null. - The provided CancellationToken - has already been disposed. - - - Calling StartNew is functionally equivalent to creating a Task using one of its constructors and - then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates and starts a Task. - - The action delegate to execute asynchronously. - An object containing data to be used by the - delegate. - A TaskCreationOptions value that controls the behavior of the - created - Task. - The started Task. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - - Calling StartNew is functionally equivalent to creating a Task using one of its constructors and - then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates and starts a Task. - - The action delegate to execute asynchronously. - An object containing data to be used by the - delegate. - The that will be assigned to the new task. - A TaskCreationOptions value that controls the behavior of the - created - Task. - The TaskScheduler - that is used to schedule the created Task. - The started Task. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - The provided CancellationToken - has already been disposed. - - - Calling StartNew is functionally equivalent to creating a Task using one of its constructors and - then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates and starts a . - - The type of the result available through the - Task. - - A function delegate that returns the future result to be available through - the . - The started . - The exception that is thrown when the - argument is null. - - Calling StartNew is functionally equivalent to creating a using one - of its constructors and then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates and starts a . - - The type of the result available through the - Task. - - A function delegate that returns the future result to be available through - the . - The that will be assigned to the new - The started . - The exception that is thrown when the - argument is null. - The provided CancellationToken - has already been disposed. - - - Calling StartNew is functionally equivalent to creating a using one - of its constructors and then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates and starts a . - - The type of the result available through the - Task. - - A function delegate that returns the future result to be available through - the . - A TaskCreationOptions value that controls the behavior of the - created - . - The started . - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - - Calling StartNew is functionally equivalent to creating a using one - of its constructors and then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates and starts a . - - The type of the result available through the - Task. - - A function delegate that returns the future result to be available through - the . - The that will be assigned to the new task. - A TaskCreationOptions value that controls the behavior of the - created - . - The TaskScheduler - that is used to schedule the created - Task{TResult}. - The started . - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - The provided CancellationToken - has already been disposed. - - - Calling StartNew is functionally equivalent to creating a using one - of its constructors and then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates and starts a . - - The type of the result available through the - Task. - - A function delegate that returns the future result to be available through - the . - An object containing data to be used by the - delegate. - The started . - The exception that is thrown when the - argument is null. - - Calling StartNew is functionally equivalent to creating a using one - of its constructors and then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates and starts a . - - The type of the result available through the - Task. - - A function delegate that returns the future result to be available through - the . - An object containing data to be used by the - delegate. - The that will be assigned to the new - The started . - The exception that is thrown when the - argument is null. - The provided CancellationToken - has already been disposed. - - - Calling StartNew is functionally equivalent to creating a using one - of its constructors and then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates and starts a . - - The type of the result available through the - Task. - - A function delegate that returns the future result to be available through - the . - An object containing data to be used by the - delegate. - A TaskCreationOptions value that controls the behavior of the - created - . - The started . - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - - Calling StartNew is functionally equivalent to creating a using one - of its constructors and then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates and starts a . - - The type of the result available through the - Task. - - A function delegate that returns the future result to be available through - the . - An object containing data to be used by the - delegate. - The that will be assigned to the new task. - A TaskCreationOptions value that controls the behavior of the - created - . - The TaskScheduler - that is used to schedule the created - Task{TResult}. - The started . - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - The provided CancellationToken - has already been disposed. - - - Calling StartNew is functionally equivalent to creating a using one - of its constructors and then calling - Start to schedule it for execution. - However, unless creation and scheduling must be separated, StartNew is the recommended approach - for both simplicity and performance. - - - - - Creates a Task that executes an end method action - when a specified IAsyncResult completes. - - The IAsyncResult whose completion should trigger the processing of the - . - The action delegate that processes the completed . - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - A Task that represents the asynchronous - operation. - - - - Creates a Task that executes an end method action - when a specified IAsyncResult completes. - - The IAsyncResult whose completion should trigger the processing of the - . - The action delegate that processes the completed . - The TaskCreationOptions value that controls the behavior of the - created Task. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - A Task that represents the asynchronous - operation. - - - - Creates a Task that executes an end method action - when a specified IAsyncResult completes. - - The IAsyncResult whose completion should trigger the processing of the - . - The action delegate that processes the completed . - The TaskScheduler - that is used to schedule the task that executes the end method. - The TaskCreationOptions value that controls the behavior of the - created Task. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - A Task that represents the asynchronous - operation. - - - - Creates a Task that represents a pair of begin - and end methods that conform to the Asynchronous Programming Model pattern. - - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The created Task that represents the - asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that represents a pair of begin - and end methods that conform to the Asynchronous Programming Model pattern. - - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - The TaskCreationOptions value that controls the behavior of the - created Task. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - The created Task that represents the - asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that represents a pair of begin - and end methods that conform to the Asynchronous Programming Model pattern. - - The type of the first argument passed to the - delegate. - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - The first argument passed to the - delegate. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The created Task that represents the - asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that represents a pair of begin - and end methods that conform to the Asynchronous Programming Model pattern. - - The type of the first argument passed to the - delegate. - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - The first argument passed to the - delegate. - The TaskCreationOptions value that controls the behavior of the - created Task. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - The created Task that represents the - asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that represents a pair of begin - and end methods that conform to the Asynchronous Programming Model pattern. - - The type of the first argument passed to the - delegate. - The type of the second argument passed to - delegate. - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - The first argument passed to the - delegate. - The second argument passed to the - delegate. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The created Task that represents the - asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that represents a pair of begin - and end methods that conform to the Asynchronous Programming Model pattern. - - The type of the first argument passed to the - delegate. - The type of the second argument passed to - delegate. - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - The first argument passed to the - delegate. - The second argument passed to the - delegate. - The TaskCreationOptions value that controls the behavior of the - created Task. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - The created Task that represents the - asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that represents a pair of begin - and end methods that conform to the Asynchronous Programming Model pattern. - - The type of the first argument passed to the - delegate. - The type of the second argument passed to - delegate. - The type of the third argument passed to - delegate. - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - The first argument passed to the - delegate. - The second argument passed to the - delegate. - The third argument passed to the - delegate. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The created Task that represents the - asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that represents a pair of begin - and end methods that conform to the Asynchronous Programming Model pattern. - - The type of the first argument passed to the - delegate. - The type of the second argument passed to - delegate. - The type of the third argument passed to - delegate. - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - The first argument passed to the - delegate. - The second argument passed to the - delegate. - The third argument passed to the - delegate. - The TaskCreationOptions value that controls the behavior of the - created Task. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - The created Task that represents the - asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that executes an end - method function when a specified IAsyncResult completes. - - The type of the result available through the - Task. - - The IAsyncResult whose completion should trigger the processing of the - . - The function delegate that processes the completed . - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - A Task that represents the - asynchronous operation. - - - - Creates a Task that executes an end - method function when a specified IAsyncResult completes. - - The type of the result available through the - Task. - - The IAsyncResult whose completion should trigger the processing of the - . - The function delegate that processes the completed . - The TaskCreationOptions value that controls the behavior of the - created Task. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - A Task that represents the - asynchronous operation. - - - - Creates a Task that executes an end - method function when a specified IAsyncResult completes. - - The type of the result available through the - Task. - - The IAsyncResult whose completion should trigger the processing of the - . - The function delegate that processes the completed . - The TaskScheduler - that is used to schedule the task that executes the end method. - The TaskCreationOptions value that controls the behavior of the - created Task. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - A Task that represents the - asynchronous operation. - - - - Creates a Task that represents a pair of - begin and end methods that conform to the Asynchronous Programming Model pattern. - - The type of the result available through the - Task. - - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The created Task that - represents the asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that represents a pair of - begin and end methods that conform to the Asynchronous Programming Model pattern. - - The type of the result available through the - Task. - - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - The TaskCreationOptions value that controls the behavior of the - created Task. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - The created Task that - represents the asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that represents a pair of - begin and end methods that conform to the Asynchronous Programming Model pattern. - - The type of the first argument passed to the delegate. - The type of the result available through the - Task. - - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - The first argument passed to the - delegate. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The created Task that - represents the asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that represents a pair of - begin and end methods that conform to the Asynchronous Programming Model pattern. - - The type of the first argument passed to the delegate. - The type of the result available through the - Task. - - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - The first argument passed to the - delegate. - The TaskCreationOptions value that controls the behavior of the - created Task. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - The created Task that - represents the asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that represents a pair of - begin and end methods that conform to the Asynchronous Programming Model pattern. - - The type of the first argument passed to the delegate. - The type of the second argument passed to - delegate. - The type of the result available through the - Task. - - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - The first argument passed to the - delegate. - The second argument passed to the - delegate. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The created Task that - represents the asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that represents a pair of - begin and end methods that conform to the Asynchronous Programming Model pattern. - - The type of the first argument passed to the delegate. - The type of the second argument passed to - delegate. - The type of the result available through the - Task. - - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - The first argument passed to the - delegate. - The second argument passed to the - delegate. - The TaskCreationOptions value that controls the behavior of the - created Task. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - The created Task that - represents the asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that represents a pair of - begin and end methods that conform to the Asynchronous Programming Model pattern. - - The type of the first argument passed to the delegate. - The type of the second argument passed to - delegate. - The type of the third argument passed to - delegate. - The type of the result available through the - Task. - - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - The first argument passed to the - delegate. - The second argument passed to the - delegate. - The third argument passed to the - delegate. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The created Task that - represents the asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Creates a Task that represents a pair of - begin and end methods that conform to the Asynchronous Programming Model pattern. - - The type of the first argument passed to the delegate. - The type of the second argument passed to - delegate. - The type of the third argument passed to - delegate. - The type of the result available through the - Task. - - The delegate that begins the asynchronous operation. - The delegate that ends the asynchronous operation. - The first argument passed to the - delegate. - The second argument passed to the - delegate. - The third argument passed to the - delegate. - The TaskCreationOptions value that controls the behavior of the - created Task. - An object containing data to be used by the - delegate. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument specifies an invalid TaskCreationOptions - value. - The created Task that - represents the asynchronous operation. - - This method throws any exceptions thrown by the . - - - - - Check validity of options passed to FromAsync method - - The options to be validated. - determines type of FromAsync method that called this method - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The array of tasks from which to continue. - The action delegate to execute when all tasks in - the array have completed. - The new continuation Task. - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The array of tasks from which to continue. - The action delegate to execute when all tasks in - the array have completed. - The CancellationToken - that will be assigned to the new continuation task. - The new continuation Task. - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The array of tasks from which to continue. - The action delegate to execute when all tasks in the array have completed. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The new continuation Task. - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAll. - - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The array of tasks from which to continue. - The action delegate to execute when all tasks in the array have completed. - The CancellationToken - that will be assigned to the new continuation task. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The TaskScheduler - that is used to schedule the created continuation Task. - The new continuation Task. - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAll. - - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The type of the result of the antecedent . - The array of tasks from which to continue. - The action delegate to execute when all tasks in - the array have completed. - The new continuation Task. - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The type of the result of the antecedent . - The array of tasks from which to continue. - The action delegate to execute when all tasks in - the array have completed. - The CancellationToken - that will be assigned to the new continuation task. - The new continuation Task. - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The type of the result of the antecedent . - The array of tasks from which to continue. - The action delegate to execute when all tasks in the array have completed. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The new continuation Task. - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAll. - - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The type of the result of the antecedent . - The array of tasks from which to continue. - The action delegate to execute when all tasks in the array have completed. - The CancellationToken - that will be assigned to the new continuation task. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The TaskScheduler - that is used to schedule the created continuation Task. - The new continuation Task. - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAll. - - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The type of the result that is returned by the - delegate and associated with the created . - The array of tasks from which to continue. - The function delegate to execute when all tasks in the - array have completed. - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The type of the result that is returned by the - delegate and associated with the created . - The array of tasks from which to continue. - The function delegate to execute when all tasks in the - array have completed. - The CancellationToken - that will be assigned to the new continuation task. - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The type of the result that is returned by the - delegate and associated with the created . - The array of tasks from which to continue. - The function delegate to execute when all tasks in the - array have completed. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAll. - - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The type of the result that is returned by the - delegate and associated with the created . - The array of tasks from which to continue. - The function delegate to execute when all tasks in the - array have completed. - The CancellationToken - that will be assigned to the new continuation task. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The TaskScheduler - that is used to schedule the created continuation . - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAll. - - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The type of the result that is returned by the - delegate and associated with the created . - The type of the result of the antecedent . - The array of tasks from which to continue. - The function delegate to execute when all tasks in the - array have completed. - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The type of the result that is returned by the - delegate and associated with the created . - The type of the result of the antecedent . - The array of tasks from which to continue. - The function delegate to execute when all tasks in the - array have completed. - The CancellationToken - that will be assigned to the new continuation task. - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The type of the result that is returned by the - delegate and associated with the created . - The type of the result of the antecedent . - The array of tasks from which to continue. - The function delegate to execute when all tasks in the - array have completed. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAll. - - - - - Creates a continuation Task - that will be started upon the completion of a set of provided Tasks. - - The type of the result that is returned by the - delegate and associated with the created . - The type of the result of the antecedent . - The array of tasks from which to continue. - The function delegate to execute when all tasks in the - array have completed. - The CancellationToken - that will be assigned to the new continuation task. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The TaskScheduler - that is used to schedule the created continuation . - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAll. - - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The array of tasks from which to continue when one task completes. - The action delegate to execute when one task in the array completes. - The new continuation Task. - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The array of tasks from which to continue when one task completes. - The action delegate to execute when one task in the array completes. - The CancellationToken - that will be assigned to the new continuation task. - The new continuation Task. - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The array of tasks from which to continue when one task completes. - The action delegate to execute when one task in the array completes. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The new continuation Task. - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAny. - - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The array of tasks from which to continue when one task completes. - The action delegate to execute when one task in the array completes. - The CancellationToken - that will be assigned to the new continuation task. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The TaskScheduler - that is used to schedule the created continuation Task. - The new continuation Task. - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAny. - - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The type of the result that is returned by the - delegate and associated with the created . - The array of tasks from which to continue when one task completes. - The function delegate to execute when one task in the - array completes. - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The type of the result that is returned by the - delegate and associated with the created . - The array of tasks from which to continue when one task completes. - The function delegate to execute when one task in the - array completes. - The CancellationToken - that will be assigned to the new continuation task. - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The type of the result that is returned by the - delegate and associated with the created . - The array of tasks from which to continue when one task completes. - The function delegate to execute when one task in the - array completes. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAny. - - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The type of the result that is returned by the - delegate and associated with the created . - The array of tasks from which to continue when one task completes. - The function delegate to execute when one task in the - array completes. - The CancellationToken - that will be assigned to the new continuation task. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The TaskScheduler - that is used to schedule the created continuation . - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAny. - - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The type of the result that is returned by the - delegate and associated with the created . - The type of the result of the antecedent . - The array of tasks from which to continue when one task completes. - The function delegate to execute when one task in the - array completes. - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The type of the result that is returned by the - delegate and associated with the created . - The type of the result of the antecedent . - The array of tasks from which to continue when one task completes. - The function delegate to execute when one task in the - array completes. - The CancellationToken - that will be assigned to the new continuation task. - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The type of the result that is returned by the - delegate and associated with the created . - The type of the result of the antecedent . - The array of tasks from which to continue when one task completes. - The function delegate to execute when one task in the - array completes. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAny. - - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The type of the result that is returned by the - delegate and associated with the created . - The type of the result of the antecedent . - The array of tasks from which to continue when one task completes. - The function delegate to execute when one task in the - array completes. - The CancellationToken - that will be assigned to the new continuation task. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The TaskScheduler - that is used to schedule the created continuation . - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAny. - - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The type of the result of the antecedent . - The array of tasks from which to continue when one task completes. - The action delegate to execute when one task in the - array completes. - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The type of the result of the antecedent . - The array of tasks from which to continue when one task completes. - The action delegate to execute when one task in the - array completes. - The CancellationToken - that will be assigned to the new continuation task. - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The type of the result of the antecedent . - The array of tasks from which to continue when one task completes. - The action delegate to execute when one task in the - array completes. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAny. - - - - - Creates a continuation Task - that will be started upon the completion of any Task in the provided set. - - The type of the result of the antecedent . - The array of tasks from which to continue when one task completes. - The action delegate to execute when one task in the - array completes. - The CancellationToken - that will be assigned to the new continuation task. - The - TaskContinuationOptions value that controls the behavior of - the created continuation Task. - The TaskScheduler - that is used to schedule the created continuation . - The new continuation . - The exception that is thrown when the - array is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - argument is null. - The exception that is thrown when the - array contains a null value. - The exception that is thrown when the - array is empty. - The exception that is thrown when the - argument specifies an invalid TaskContinuationOptions - value. - The exception that is thrown when one - of the elements in the array has been disposed. - The provided CancellationToken - has already been disposed. - - - The NotOn* and OnlyOn* TaskContinuationOptions, - which constrain for which TaskStatus states a continuation - will be executed, are illegal with ContinueWhenAny. - - - - - Gets the default CancellationToken of this - TaskFactory. - - - This property returns the default that will be assigned to all - tasks created by this factory unless another CancellationToken value is explicitly specified - during the call to the factory methods. - - - - - Gets the TaskScheduler of this - TaskFactory. - - - This property returns the default scheduler for this factory. It will be used to schedule all - tasks unless another scheduler is explicitly specified during calls to this factory's methods. - If null, TaskScheduler.Current - will be used. - - - - - Gets the TaskCreationOptions - value of this TaskFactory. - - - This property returns the default creation options for this factory. They will be used to create all - tasks unless other options are explicitly specified during calls to this factory's methods. - - - - - Gets the TaskContinuationOptions - value of this TaskFactory. - - - This property returns the default continuation options for this factory. They will be used to create - all continuation tasks unless other options are explicitly specified during calls to this factory's methods. - - - - - Represents the producer side of a unbound to a - delegate, providing access to the consumer side through the property. - - - - It is often the case that a is desired to - represent another asynchronous operation. - TaskCompletionSource is provided for this purpose. It enables - the creation of a task that can be handed out to consumers, and those consumers can use the members - of the task as they would any other. However, unlike most tasks, the state of a task created by a - TaskCompletionSource is controlled explicitly by the methods on TaskCompletionSource. This enables the - completion of the external asynchronous operation to be propagated to the underlying Task. The - separation also ensures that consumers are not able to transition the state without access to the - corresponding TaskCompletionSource. - - - All members of are thread-safe - and may be used from multiple threads concurrently. - - - The type of the result value assocatied with this . - - - - Creates a . - - - - - Creates a - with the specified options. - - - The created - by this instance and accessible through its property - will be instantiated using the specified . - - The options to use when creating the underlying - . - - The represent options invalid for use - with a . - - - - - Creates a - with the specified state. - - The state to use as the underlying - 's AsyncState. - - - - Creates a with - the specified state and options. - - The options to use when creating the underlying - . - The state to use as the underlying - 's AsyncState. - - The represent options invalid for use - with a . - - - - - Attempts to transition the underlying - into the - Faulted - state. - - The exception to bind to this . - True if the operation was successful; otherwise, false. - This operation will return false if the - is already in one - of the three final states: - RanToCompletion, - Faulted, or - Canceled. - - The argument is null. - The was disposed. - - - - Attempts to transition the underlying - into the - Faulted - state. - - The collection of exceptions to bind to this . - True if the operation was successful; otherwise, false. - This operation will return false if the - is already in one - of the three final states: - RanToCompletion, - Faulted, or - Canceled. - - The argument is null. - There are one or more null elements in . - The collection is empty. - The was disposed. - - - - Transitions the underlying - into the - Faulted - state. - - The exception to bind to this . - The argument is null. - - The underlying is already in one - of the three final states: - RanToCompletion, - Faulted, or - Canceled. - - The was disposed. - - - - Transitions the underlying - into the - Faulted - state. - - The collection of exceptions to bind to this . - The argument is null. - There are one or more null elements in . - - The underlying is already in one - of the three final states: - RanToCompletion, - Faulted, or - Canceled. - - The was disposed. - - - - Attempts to transition the underlying - into the - RanToCompletion - state. - - The result value to bind to this . - True if the operation was successful; otherwise, false. - This operation will return false if the - is already in one - of the three final states: - RanToCompletion, - Faulted, or - Canceled. - - The was disposed. - - - - Transitions the underlying - into the - RanToCompletion - state. - - The result value to bind to this . - - The underlying is already in one - of the three final states: - RanToCompletion, - Faulted, or - Canceled. - - The was disposed. - - - - Transitions the underlying - into the - Canceled - state. - - - The underlying is already in one - of the three final states: - RanToCompletion, - Faulted, or - Canceled. - - The was disposed. - - - - Attempts to transition the underlying - into the - Canceled - state. - - True if the operation was successful; otherwise, false. - This operation will return false if the - is already in one - of the three final states: - RanToCompletion, - Faulted, or - Canceled. - - The was disposed. - - - - Gets the created - by this . - - - This property enables a consumer access to the that is controlled by this instance. - The , , - , and - methods (and their "Try" variants) on this instance all result in the relevant state - transitions on this underlying Task. - - - - - Represents an abstract scheduler for tasks. - - - - TaskScheduler acts as the extension point for all - pluggable scheduling logic. This includes mechanisms such as how to schedule a task for execution, and - how scheduled tasks should be exposed to debuggers. - - - All members of the abstract type are thread-safe - and may be used from multiple threads concurrently. - - - - - - Queues a Task to the scheduler. - - - - A class derived from TaskScheduler - implements this method to accept tasks being scheduled on the scheduler. - A typical implementation would store the task in an internal data structure, which would - be serviced by threads that would execute those tasks at some time in the future. - - - This method is only meant to be called by the .NET Framework and - should not be called directly by the derived class. This is necessary - for maintaining the consistency of the system. - - - The Task to be queued. - The argument is null. - - - - Determines whether the provided Task - can be executed synchronously in this call, and if it can, executes it. - - - - A class derived from TaskScheduler implements this function to - support inline execution of a task on a thread that initiates a wait on that task object. Inline - execution is optional, and the request may be rejected by returning false. However, better - scalability typically results the more tasks that can be inlined, and in fact a scheduler that - inlines too little may be prone to deadlocks. A proper implementation should ensure that a - request executing under the policies guaranteed by the scheduler can successfully inline. For - example, if a scheduler uses a dedicated thread to execute tasks, any inlining requests from that - thread should succeed. - - - If a scheduler decides to perform the inline execution, it should do so by calling to the base - TaskScheduler's - TryExecuteTask method with the provided task object, propagating - the return value. It may also be appropriate for the scheduler to remove an inlined task from its - internal data structures if it decides to honor the inlining request. Note, however, that under - some circumstances a scheduler may be asked to inline a task that was not previously provided to - it with the method. - - - The derived scheduler is responsible for making sure that the calling thread is suitable for - executing the given task as far as its own scheduling and execution policies are concerned. - - - The Task to be - executed. - A Boolean denoting whether or not task has previously been - queued. If this parameter is True, then the task may have been previously queued (scheduled); if - False, then the task is known not to have been queued, and this call is being made in order to - execute the task inline without queueing it. - A Boolean value indicating whether the task was executed inline. - The argument is - null. - The was already - executed. - - - - Generates an enumerable of Task instances - currently queued to the scheduler waiting to be executed. - - - - A class derived from implements this method in order to support - integration with debuggers. This method will only be invoked by the .NET Framework when the - debugger requests access to the data. The enumerable returned will be traversed by debugging - utilities to access the tasks currently queued to this scheduler, enabling the debugger to - provide a representation of this information in the user interface. - - - It is important to note that, when this method is called, all other threads in the process will - be frozen. Therefore, it's important to avoid synchronization with other threads that may lead to - blocking. If synchronization is necessary, the method should prefer to throw a - than to block, which could cause a debugger to experience delays. Additionally, this method and - the enumerable returned must not modify any globally visible state. - - - The returned enumerable should never be null. If there are currently no queued tasks, an empty - enumerable should be returned instead. - - - For developers implementing a custom debugger, this method shouldn't be called directly, but - rather this functionality should be accessed through the internal wrapper method - GetScheduledTasksForDebugger: - internal Task[] GetScheduledTasksForDebugger(). This method returns an array of tasks, - rather than an enumerable. In order to retrieve a list of active schedulers, a debugger may use - another internal method: internal static TaskScheduler[] GetTaskSchedulersForDebugger(). - This static method returns an array of all active TaskScheduler instances. - GetScheduledTasksForDebugger then may be used on each of these scheduler instances to retrieve - the list of scheduled tasks for each. - - - An enumerable that allows traversal of tasks currently queued to this scheduler. - - - This scheduler is unable to generate a list of queued tasks at this time. - - - - - Retrieves some thread static state that can be cached and passed to multiple - TryRunInline calls, avoiding superflous TLS fetches. - - A bag of TLS state (or null if none exists). - - - - Attempts to execute the target task synchronously. - - The task to run. - True if the task may have been previously queued, - false if the task was absolutely not previously queued. - The state retrieved from GetThreadStatics - True if it ran, false otherwise. - - - - Attempts to dequeue a Task that was previously queued to - this scheduler. - - The Task to be dequeued. - A Boolean denoting whether the argument was successfully dequeued. - The argument is null. - - - - Notifies the scheduler that a work item has made progress. - - - - - Initializes the . - - - - - Frees all resources associated with this scheduler. - - - - - Creates a - associated with the current . - - - All Task instances queued to - the returned scheduler will be executed through a call to the - Post method - on that context. - - - A associated with - the current SynchronizationContext, as - determined by SynchronizationContext.Current. - - - The current SynchronizationContext may not be used as a TaskScheduler. - - - - - Attempts to execute the provided Task - on this scheduler. - - - - Scheduler implementations are provided with Task - instances to be executed through either the method or the - method. When the scheduler deems it appropriate to run the - provided task, should be used to do so. TryExecuteTask handles all - aspects of executing a task, including action invocation, exception handling, state management, - and lifecycle control. - - - must only be used for tasks provided to this scheduler by the .NET - Framework infrastructure. It should not be used to execute arbitrary tasks obtained through - custom mechanisms. - - - - A Task object to be executed. - - The is not associated with this scheduler. - - A Boolean that is true if was successfully executed, false if it - was not. A common reason for execution failure is that the task had previously been executed or - is in the process of being executed by another thread. - - - - Provides an array of all queued Task instances - for the debugger. - - - The returned array is populated through a call to . - Note that this function is only meant to be invoked by a debugger remotely. - It should not be called by any other codepaths. - - An array of Task instances. - - This scheduler is unable to generate a list of queued tasks at this time. - - - - - Provides an array of all active TaskScheduler - instances for the debugger. - - - This function is only meant to be invoked by a debugger remotely. - It should not be called by any other codepaths. - - An array of TaskScheduler instances. - - - - Registers a new TaskScheduler instance in the global collection of schedulers. - - - - - Removes a TaskScheduler instance from the global collection of schedulers. - - - - - Indicates the maximum concurrency level this - is able to support. - - - - - Indicates whether this is a custom scheduler, in which case the safe code paths will be taken upon task entry - using a CAS to transition from queued state to executing. - - - - - Gets the default TaskScheduler instance. - - - - - Gets the TaskScheduler - associated with the currently executing task. - - - When not called from within a task, will return the scheduler. - - - - - Gets the unique ID for this . - - - - - Occurs when a faulted 's unobserved exception is about to trigger exception escalation - policy, which, by default, would terminate the process. - - - This AppDomain-wide event provides a mechanism to prevent exception - escalation policy (which, by default, terminates the process) from triggering. - Each handler is passed a - instance, which may be used to examine the exception and to mark it as observed. - - - - - Nested class that provides debugger view for TaskScheduler - - - - - A TaskScheduler implementation that executes all tasks queued to it through a call to - on the - that its associated with. The default constructor for this class binds to the current - - - - - Constructs a SynchronizationContextTaskScheduler associated with - - This constructor expects to be set. - - - - Implemetation of for this scheduler class. - - Simply posts the tasks to be executed on the associated . - - - - - - Implementation of for this scheduler class. - - The task will be executed inline only if the call happens within - the associated . - - - - - - - Implementes the property for - this scheduler class. - - By default it returns 1, because a based - scheduler only supports execution on a single thread. - - - - - Provides data for the event that is raised when a faulted 's - exception goes unobserved. - - - The Exception property is used to examine the exception without marking it - as observed, whereas the method is used to mark the exception - as observed. Marking the exception as observed prevents it from triggering exception escalation policy - which, by default, terminates the process. - - - - - Initializes a new instance of the class - with the unobserved exception. - - The Exception that has gone unobserved. - - - - Marks the as "observed," thus preventing it - from triggering exception escalation policy which, by default, terminates the process. - - - - - Gets whether this exception has been marked as "observed." - - - - - The Exception that went unobserved. - - - - - An implementation of TaskScheduler that uses the ThreadPool scheduler - - - - - Constructs a new ThreadPool task scheduler object - - - - - Schedules a task to the ThreadPool. - - The task to schedule. - - - - This internal function will do this: - (1) If the task had previously been queued, attempt to pop it and return false if that fails. - (2) Propagate the return value from Task.ExecuteEntry() back to the caller. - - IMPORTANT NOTE: TryExecuteTaskInline will NOT throw task exceptions itself. Any wait code path using this function needs - to account for exceptions that need to be propagated, and throw themselves accordingly. - - - - - Notifies the scheduler that work is progressing (no-op). - - - - - This is the only scheduler that returns false for this property, indicating that the task entry codepath is unsafe (CAS free) - since we know that the underlying scheduler already takes care of atomic transitions from queued to non-queued. - - - - - Represents an exception used to communicate an invalid operation by a - . - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the - class with a specified error message. - - The error message that explains the reason for the exception. - - - - Initializes a new instance of the - class using the default error message and a reference to the inner exception that is the cause of - this exception. - - The exception that is the cause of the current exception. - - - - Initializes a new instance of the - class with a specified error message and a reference to the inner exception that is the cause of - this exception. - - The error message that explains the reason for the exception. - The exception that is the cause of the current exception. - - - - Initializes a new instance of the - class with serialized data. - - The that holds - the serialized object data about the exception being thrown. - The that - contains contextual information about the source or destination. - - - - The exception that is thrown when the post-phase action of a fails. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with the specified inner exception. - - The exception that is the cause of the current exception. - - - - Initializes a new instance of the class with a specified error message. - - A string that describes the exception. - - - - Initializes a new instance of the class with a specified error message and inner exception. - - A string that describes the exception. - The exception that is the cause of the current exception. - - - - Initializes a new instance of the class with serialized data. - - The object that holds the serialized object data. - An object that describes the source or destination of the serialized data. - - - - Enables multiple tasks to cooperatively work on an algorithm in parallel through multiple phases. - - - - A group of tasks cooperate by moving through a series of phases, where each in the group signals it - has arrived at the in a given phase and implicitly waits for all others to - arrive. The same can be used for multiple phases. - - - All public and protected members of are thread-safe and may be used - concurrently from multiple threads, with the exception of Dispose, which - must only be used when all other operations on the have - completed. - - - - - - Initializes a new instance of the class. - - The number of participating threads. - is less than 0 - or greater than . - - - - Initializes a new instance of the class. - - The number of participating threads. - The to be executed after each - phase. - is less than 0 - or greater than . - - The delegate will be executed after - all participants have arrived at the barrier in one phase. The participants - will not be released to the next phase until the postPhaseAction delegate - has completed execution. - - - - - Extract the three variables current, total and sense from a given big variable - - The integer variable that contains the other three variables - The current cparticipant count - The total participants count - The sense flag - - - - Write the three variables current. total and the sense to the m_currentTotal - - The old current total to compare - The current cparticipant count - The total participants count - The sense flag - True if the CAS succeeded, false otherwise - - - - Notifies the that there will be an additional participant. - - The phase number of the barrier in which the new participants will first - participate. - - Adding a participant would cause the barrier's participant count to - exceed . - - - The method was invoked from within a post-phase action. - - The current instance has already been - disposed. - - - - Notifies the that there will be additional participants. - - The number of additional participants to add to the - barrier. - The phase number of the barrier in which the new participants will first - participate. - is less than - 0. - Adding participants would cause the - barrier's participant count to exceed . - - The method was invoked from within a post-phase action. - - The current instance has already been - disposed. - - - - Notifies the that there will be one less participant. - - The barrier already has 0 - participants. - - The method was invoked from within a post-phase action. - - The current instance has already been - disposed. - - - - Notifies the that there will be fewer participants. - - The number of additional participants to remove from the barrier. - is less than - 0. - The barrier already has 0 participants. - - The method was invoked from within a post-phase action. - - The current instance has already been - disposed. - - - - Signals that a participant has reached the and waits for all other - participants to reach the barrier as well. - - - The method was invoked from within a post-phase action, the barrier currently has 0 participants, - or the barrier is being used by more threads than are registered as participants. - - The current instance has already been - disposed. - - - - Signals that a participant has reached the and waits for all other - participants to reach the barrier, while observing a . - - The to - observe. - - The method was invoked from within a post-phase action, the barrier currently has 0 participants, - or the barrier is being used by more threads than are registered as participants. - - has been - canceled. - The current instance has already been - disposed. - - - - Signals that a participant has reached the and waits for all other - participants to reach the barrier as well, using a - to measure the time interval. - - A that represents the number of - milliseconds to wait, or a that represents -1 milliseconds to - wait indefinitely. - true if all other participants reached the barrier; otherwise, false. - is a negative number - other than -1 milliseconds, which represents an infinite time-out, or it is greater than - . - - The method was invoked from within a post-phase action, the barrier currently has 0 participants, - or the barrier is being used by more threads than are registered as participants. - - The current instance has already been - disposed. - - - - Signals that a participant has reached the and waits for all other - participants to reach the barrier as well, using a - to measure the time interval, while observing a . - - A that represents the number of - milliseconds to wait, or a that represents -1 milliseconds to - wait indefinitely. - The to - observe. - true if all other participants reached the barrier; otherwise, false. - is a negative number - other than -1 milliseconds, which represents an infinite time-out. - - The method was invoked from within a post-phase action, the barrier currently has 0 participants, - or the barrier is being used by more threads than are registered as participants. - - has been - canceled. - The current instance has already been - disposed. - - - - Signals that a participant has reached the and waits for all other - participants to reach the barrier as well, using a - 32-bit signed integer to measure the time interval. - - The number of milliseconds to wait, or (-1) to wait indefinitely. - true if all other participants reached the barrier; otherwise, false. - is a - negative number other than -1, which represents an infinite time-out. - - The method was invoked from within a post-phase action, the barrier currently has 0 participants, - or the barrier is being used by more threads than are registered as participants. - - The current instance has already been - disposed. - - - - Signals that a participant has reached the barrier and waits for all other participants to reach - the barrier as well, using a - 32-bit signed integer to measure the time interval, while observing a . - - The number of milliseconds to wait, or (-1) to wait indefinitely. - The to - observe. - true if all other participants reached the barrier; otherwise, false. - is a - negative number other than -1, which represents an infinite time-out. - - The method was invoked from within a post-phase action, the barrier currently has 0 participants, - or the barrier is being used by more threads than are registered as participants. - - has been - canceled. - The current instance has already been - disposed. - - - - Finish the phase by invoking the post phase action, and setting the event, this must be called by the - last arrival thread - - The current phase sense - - - - Sets the current phase event and reset the next phase event - - The current phase sense - - - - Releases all resources used by the current instance of . - - - The method was invoked from within a post-phase action. - - - Unlike most of the members of , Dispose is not thread-safe and may not be - used concurrently with other members of this instance. - - - - - When overridden in a derived class, releases the unmanaged resources used by the - , and optionally releases the managed resources. - - true to release both managed and unmanaged resources; false to release - only unmanaged resources. - - Unlike most of the members of , Dispose is not thread-safe and may not be - used concurrently with other members of this instance. - - - - - Throw ObjectDisposedException if the barrier is disposed - - - - - Gets the number of participants in the barrier that haven’t yet signaled - in the current phase. - - - This could be 0 during a post-phase action delegate execution or if the - ParticipantCount is 0. - - - - - Gets the total number of participants in the barrier. - - - - - Gets the number of the barrier's current phase. - - - - - Provides blocking and bounding capabilities for thread-safe collections that - implement . - - - represents a collection - that allows for thread-safe adding and removing of data. - is used as a wrapper - for an instance, allowing - removal attempts from the collection to block until data is available to be removed. Similarly, - a can be created to enforce - an upper-bound on the number of data elements allowed in the - ; addition attempts to the - collection may then block until space is available to store the added items. In this manner, - is similar to a traditional - blocking queue data structure, except that the underlying data storage mechanism is abstracted - away as an . - - Specifies the type of elements in the collection. - - - Initializes a new instance of the - - class without an upper-bound. - - - The default underlying collection is a ConcurrentQueue<T>. - - - - Initializes a new instance of the - class with the specified upper-bound. - - The bounded size of the collection. - The is - not a positive value. - - The default underlying collection is a ConcurrentQueue<T>. - - - - Initializes a new instance of the - class with the specified upper-bound and using the provided - as its underlying data store. - The collection to use as the underlying data store. - The bounded size of the collection. - The argument is - null. - The is not a positive value. - The supplied contains more values - than is permitted by . - - - Initializes a new instance of the - class without an upper-bound and using the provided - as its underlying data store. - The collection to use as the underlying data store. - The argument is - null. - - - Initializes the BlockingCollection instance. - The collection to use as the underlying data store. - The bounded size of the collection. - The number of items currently in the underlying collection. - - - - Adds the item to the . - - The item to be added to the collection. The value can be a null reference. - The has been marked - as complete with regards to additions. - The has been disposed. - The underlying collection didn't accept the item. - - If a bounded capacity was specified when this instance of - was initialized, - a call to Add may block until space is available to store the provided item. - - - - - Adds the item to the . - A is thrown if the is - canceled. - - The item to be added to the collection. The value can be a null reference. - A cancellation token to observe. - If the is canceled. - The has been marked - as complete with regards to additions. - The has been disposed. - The underlying collection didn't accept the item. - - If a bounded capacity was specified when this instance of - was initialized, - a call to may block until space is available to store the provided item. - - - - - Attempts to add the specified item to the . - - The item to be added to the collection. - true if the could be added; otherwise, false. - The has been marked - as complete with regards to additions. - The has been disposed. - The underlying collection didn't accept the item. - - - - Attempts to add the specified item to the . - - The item to be added to the collection. - A that represents the number of milliseconds - to wait, or a that represents -1 milliseconds to wait indefinitely. - - true if the could be added to the collection within - the alloted time; otherwise, false. - The has been marked - as complete with regards to additions. - The has been disposed. - is a negative number - other than -1 milliseconds, which represents an infinite time-out -or- timeout is greater than - . - The underlying collection didn't accept the item. - - - - Attempts to add the specified item to the . - - The item to be added to the collection. - The number of milliseconds to wait, or (-1) to wait indefinitely. - true if the could be added to the collection within - the alloted time; otherwise, false. - The has been marked - as complete with regards to additions. - The has been disposed. - is a - negative number other than -1, which represents an infinite time-out. - The underlying collection didn't accept the item. - - - - Attempts to add the specified item to the . - A is thrown if the is - canceled. - - The item to be added to the collection. - The number of milliseconds to wait, or (-1) to wait indefinitely. - A cancellation token to observe. - true if the could be added to the collection within - the alloted time; otherwise, false. - If the is canceled. - The has been marked - as complete with regards to additions. - The has been disposed. - is a - negative number other than -1, which represents an infinite time-out. - The underlying collection didn't accept the item. - - - Adds an item into the underlying data store using its IProducerConsumerCollection<T>.Add - method. If a bounded capacity was specified and the collection was full, - this method will wait for, at most, the timeout period trying to add the item. - If the timeout period was exhaused before successfully adding the item this method will - return false. - The item to be added to the collection. - The number of milliseconds to wait for the collection to accept the item, - or Timeout.Infinite to wait indefinitely. - A cancellation token to observe. - False if the collection remained full till the timeout period was exhausted.True otherwise. - If the is canceled. - the collection has already been marked - as complete with regards to additions. - If the collection has been disposed. - The underlying collection didn't accept the item. - - - Takes an item from the . - The item removed from the collection. - The is empty and has been marked - as complete with regards to additions. - The has been disposed. - The underlying collection was modified - outside of this instance. - A call to may block until an item is available to be removed. - - - Takes an item from the . - The item removed from the collection. - If the is - canceled or the is empty and has been marked - as complete with regards to additions. - The has been disposed. - The underlying collection was modified - outside of this instance. - A call to may block until an item is available to be removed. - - - - Attempts to remove an item from the . - - The item removed from the collection. - true if an item could be removed; otherwise, false. - The has been disposed. - The underlying collection was modified - outside of this instance. - - - - Attempts to remove an item from the . - - The item removed from the collection. - A that represents the number of milliseconds - to wait, or a that represents -1 milliseconds to wait indefinitely. - - true if an item could be removed from the collection within - the alloted time; otherwise, false. - The has been disposed. - is a negative number - other than -1 milliseconds, which represents an infinite time-out -or- timeout is greater than - . - The underlying collection was modified - outside of this instance. - - - - Attempts to remove an item from the . - - The item removed from the collection. - The number of milliseconds to wait, or (-1) to wait indefinitely. - true if an item could be removed from the collection within - the alloted time; otherwise, false. - The has been disposed. - is a - negative number other than -1, which represents an infinite time-out. - The underlying collection was modified - outside of this instance. - - - - Attempts to remove an item from the . - A is thrown if the is - canceled. - - The item removed from the collection. - The number of milliseconds to wait, or (-1) to wait indefinitely. - A cancellation token to observe. - true if an item could be removed from the collection within - the alloted time; otherwise, false. - If the is canceled. - The has been disposed. - is a - negative number other than -1, which represents an infinite time-out. - The underlying collection was modified - outside of this instance. - - - Takes an item from the underlying data store using its IProducerConsumerCollection<T>.Take - method. If the collection was empty, this method will wait for, at most, the timeout period (if AddingIsCompleted is false) - trying to remove an item. If the timeout period was exhaused before successfully removing an item - this method will return false. - A is thrown if the is - canceled. - - The item removed from the collection. - The number of milliseconds to wait for the collection to have an item available - for removal, or Timeout.Infinite to wait indefinitely. - A cancellation token to observe. - A combined cancellation token if created, it is only created by GetConsumingEnumerable to avoid creating the linked token - multiple times. - False if the collection remained empty till the timeout period was exhausted. True otherwise. - If the is canceled. - If the collection has been disposed. - - - - Adds the specified item to any one of the specified - instances. - - The array of collections. - The item to be added to one of the collections. - The index of the collection in the array to which the item was added. - The argument is - null. - The argument is - a 0-length array or contains a null element, or at least one of collections has been - marked as complete for adding. - At least one of the instances has been disposed. - At least one underlying collection didn't accept the item. - The count of is greater than the maximum size of - 62 for STA and 63 for MTA. - - If a bounded capacity was specified when all of the - instances were initialized, - a call to AddToAny may block until space is available in one of the collections - to store the provided item. - - - - - Adds the specified item to any one of the specified - instances. - A is thrown if the is - canceled. - - The array of collections. - The item to be added to one of the collections. - A cancellation token to observe. - The index of the collection in the array to which the item was added. - If the is canceled. - The argument is - null. - The argument is - a 0-length array or contains a null element, or at least one of collections has been - marked as complete for adding. - At least one of the instances has been disposed. - At least one underlying collection didn't accept the item. - The count of is greater than the maximum size of - 62 for STA and 63 for MTA. - - If a bounded capacity was specified when all of the - instances were initialized, - a call to AddToAny may block until space is available in one of the collections - to store the provided item. - - - - - Attempts to add the specified item to any one of the specified - instances. - - The array of collections. - The item to be added to one of the collections. - The index of the collection in the - array to which the item was added, or -1 if the item could not be added. - The argument is - null. - The argument is - a 0-length array or contains a null element, or at least one of collections has been - marked as complete for adding. - At least one of the instances has been disposed. - At least one underlying collection didn't accept the item. - The count of is greater than the maximum size of - 62 for STA and 63 for MTA. - - - - Attempts to add the specified item to any one of the specified - instances. - - The array of collections. - The item to be added to one of the collections. - A that represents the number of milliseconds - to wait, or a that represents -1 milliseconds to wait indefinitely. - - The index of the collection in the - array to which the item was added, or -1 if the item could not be added. - The argument is - null. - The argument is - a 0-length array or contains a null element, or at least one of collections has been - marked as complete for adding. - At least one of the instances has been disposed. - is a negative number - other than -1 milliseconds, which represents an infinite time-out -or- timeout is greater than - . - At least one underlying collection didn't accept the item. - The count of is greater than the maximum size of - 62 for STA and 63 for MTA. - - - - Attempts to add the specified item to any one of the specified - instances. - - The array of collections. - The item to be added to one of the collections. - The number of milliseconds to wait, or (-1) to wait indefinitely. /// The index of the collection in the - array to which the item was added, or -1 if the item could not be added. - The argument is - null. - The argument is - a 0-length array or contains a null element, or at least one of collections has been - marked as complete for adding. - At least one of the instances has been disposed. - is a - negative number other than -1, which represents an infinite time-out. - At least one underlying collection didn't accept the item. - The count of is greater than the maximum size of - 62 for STA and 63 for MTA. - - - - Attempts to add the specified item to any one of the specified - instances. - A is thrown if the is - canceled. - - The array of collections. - The item to be added to one of the collections. - The number of milliseconds to wait, or (-1) to wait indefinitely. /// The index of the collection in the - array to which the item was added, or -1 if the item could not be added. - A cancellation token to observe. - If the is canceled. - The argument is - null. - The argument is - a 0-length array or contains a null element, or at least one of collections has been - marked as complete for adding. - At least one of the instances has been disposed. - is a - negative number other than -1, which represents an infinite time-out. - At least one underlying collection didn't accept the item. - The count of is greater than the maximum size of - 62 for STA and 63 for MTA. - - - Adds/Takes an item to/from anyone of the specified collections. - A is thrown if the is - canceled. - - The collections into which the item can be added. - The item to be added or the item removed and returned to the caller. - The number of milliseconds to wait for a collection to accept the - operation, or -1 to wait indefinitely. - Indicates whether this method is called to Add or Take. - A cancellation token to observe. - The index into collections for the collection which accepted the - adding/removal of the item; -1 if the item could not be added/removed. - If the is canceled. - If the collections argument is null. - If the collections argument is a 0-length array or contains a - null element. Also, if atleast one of the collections has been marked complete for adds. - If atleast one of the collections has been disposed. - - - - Local static method, used by TryAddTakeAny to get the wait handles for the collection, with exclude option to exclude the Compeleted collections - - The blocking collections - Add or Take operation - The original CancellationToken - True to exclude the compeleted collections - Complete list of cancellationTokens to observe - The collections wait handles - - - - Helper to perform WaitHandle.WaitAny(.., CancellationToken) - this should eventually appear on the WaitHandle class. - - - - - - - - - - Helper function to measure and update the wait time - - The first time (in Ticks) observed when the wait started - The orginal wait timeoutout in milliseconds - The new wait time in milliseconds, -1 if the time expired - - - - Takes an item from any one of the specified - instances. - - The array of collections. - The item removed from one of the collections. - The index of the collection in the array from which - the item was removed, or -1 if an item could not be removed. - The argument is - null. - The argument is - a 0-length array or contains a null element. - At least one of the instances has been disposed. - At least one of the underlying collections was modified - outside of its instance. - The count of is greater than the maximum size of - 62 for STA and 63 for MTA. - A call to TakeFromAny may block until an item is available to be removed. - - - - Takes an item from any one of the specified - instances. - A is thrown if the is - canceled. - - The array of collections. - The item removed from one of the collections. - A cancellation token to observe. - The index of the collection in the array from which - the item was removed, or -1 if an item could not be removed. - The argument is - null. - If the is canceled. - The argument is - a 0-length array or contains a null element. - At least one of the instances has been disposed. - At least one of the underlying collections was modified - outside of its instance. - The count of is greater than the maximum size of - 62 for STA and 63 for MTA. - A call to TakeFromAny may block until an item is available to be removed. - - - - Attempts to remove an item from any one of the specified - instances. - - The array of collections. - The item removed from one of the collections. - The index of the collection in the array from which - the item was removed, or -1 if an item could not be removed. - The argument is - null. - The argument is - a 0-length array or contains a null element. - At least one of the instances has been disposed. - At least one of the underlying collections was modified - outside of its instance. - The count of is greater than the maximum size of - 62 for STA and 63 for MTA. - A call to TryTakeFromAny may block until an item is available to be removed. - - - - Attempts to remove an item from any one of the specified - instances. - - The array of collections. - The item removed from one of the collections. - A that represents the number of milliseconds - to wait, or a that represents -1 milliseconds to wait indefinitely. - - The index of the collection in the array from which - the item was removed, or -1 if an item could not be removed. - The argument is - null. - The argument is - a 0-length array or contains a null element. - At least one of the instances has been disposed. - is a negative number - other than -1 milliseconds, which represents an infinite time-out -or- timeout is greater than - . - At least one of the underlying collections was modified - outside of its instance. - The count of is greater than the maximum size of - 62 for STA and 63 for MTA. - A call to TryTakeFromAny may block until an item is available to be removed. - - - - Attempts to remove an item from any one of the specified - instances. - - The array of collections. - The item removed from one of the collections. - The number of milliseconds to wait, or (-1) to wait indefinitely. - The index of the collection in the array from which - the item was removed, or -1 if an item could not be removed. - The argument is - null. - The argument is - a 0-length array or contains a null element. - At least one of the instances has been disposed. - is a - negative number other than -1, which represents an infinite time-out. - At least one of the underlying collections was modified - outside of its instance. - The count of is greater than the maximum size of - 62 for STA and 63 for MTA. - A call to TryTakeFromAny may block until an item is available to be removed. - - - - Attempts to remove an item from any one of the specified - instances. - A is thrown if the is - canceled. - - The array of collections. - The item removed from one of the collections. - The number of milliseconds to wait, or (-1) to wait indefinitely. - A cancellation token to observe. - The index of the collection in the array from which - the item was removed, or -1 if an item could not be removed. - If the is canceled. - The argument is - null. - The argument is - a 0-length array or contains a null element. - At least one of the instances has been disposed. - is a - negative number other than -1, which represents an infinite time-out. - At least one of the underlying collections was modified - outside of its instance. - The count of is greater than the maximum size of - 62 for STA and 63 for MTA. - A call to TryTakeFromAny may block until an item is available to be removed. - - - - Marks the instances - as not accepting any more additions. - - - After a collection has been marked as complete for adding, adding to the collection is not permitted - and attempts to remove from the collection will not wait when the collection is empty. - - The has been disposed. - - - Cancels the semaphores. - - - - Releases resources used by the instance. - - - - - Releases resources used by the instance. - - Whether being disposed explicitly (true) or due to a finalizer (false). - - - Copies the items from the instance into a new array. - An array containing copies of the elements of the collection. - The has been disposed. - - The copied elements are not removed from the collection. - - - - Copies all of the items in the instance - to a compatible one-dimensional array, starting at the specified index of the target array. - - The one-dimensional array that is the destination of the elements copied from - the instance. The array must have zero-based indexing. - The zero-based index in at which copying begins. - The argument is - null. - The argument is less than zero. - The argument is equal to or greater - than the length of the . - The has been disposed. - - - Copies all of the items in the instance - to a compatible one-dimensional array, starting at the specified index of the target array. - - The one-dimensional array that is the destination of the elements copied from - the instance. The array must have zero-based indexing. - The zero-based index in at which copying begins. - The argument is - null. - The argument is less than zero. - The argument is equal to or greater - than the length of the , the array is multidimensional, or the type parameter for the collection - cannot be cast automatically to the type of the destination array. - The has been disposed. - - - Provides a consuming for items in the collection. - An that removes and returns items from the collection. - The has been disposed. - - - Provides a consuming for items in the collection. - Calling MoveNext on the returned enumerable will block if there is no data available, or will - throw an if the is canceled. - - A cancellation token to observe. - An that removes and returns items from the collection. - The has been disposed. - If the is canceled. - - - Provides an for items in the collection. - An for the items in the collection. - The has been disposed. - - - Provides an for items in the collection. - An for the items in the collection. - The has been disposed. - - - Centralizes the logic for validating the BlockingCollections array passed to TryAddToAny() - and TryTakeFromAny(). - The collections to/from which an item should be added/removed. - Indicates whether this method is called to Add or Take. - A copy of the collections array that acts as a defense to prevent an “outsider” from changing - elements of the array after we have done the validation on them. - If the collections argument is null. - If the collections argument is a 0-length array or contains a - null element. Also, if atleast one of the collections has been marked complete for adds. - If atleast one of the collections has been disposed. - - - Centeralizes the logic of validating the timeout input argument. - The TimeSpan to wait for to successfully complete an operation on the collection. - If the number of millseconds represented by the timeout - TimeSpan is less than 0 or is larger than Int32.MaxValue and not Timeout.Infinite - - - Centralizes the logic of validating the millisecondsTimeout input argument. - The number of milliseconds to wait for to successfully complete an - operation on the collection. - If the number of millseconds is less than 0 and not - equal to Timeout.Infinite. - - - Throws a System.ObjectDisposedException if the collection was disposed - If the collection has been disposed. - - - Gets the bounded capacity of this instance. - The bounded capacity of this collection, or int.MaxValue if no bound was supplied. - The has been disposed. - - - Gets whether this has been marked as complete for adding. - Whether this collection has been marked as complete for adding. - The has been disposed. - - - Gets whether this has been marked as complete for adding and is empty. - Whether this collection has been marked as complete for adding and is empty. - The has been disposed. - - - Gets the number of items contained in the . - The number of items contained in the . - The has been disposed. - - - Gets a value indicating whether access to the is synchronized. - The has been disposed. - - - - Gets an object that can be used to synchronize access to the . This property is not supported. - - The SyncRoot property is not supported. - - - An enumerated data type used internal to the class to specify to a generic method - the current mode of operation. - - - A debugger view of the blocking collection that makes it simple to browse the - collection's contents at a point in time. - The type of element that the BlockingCollection will hold. - - - Constructs a new debugger view object for the provided blocking collection object. - A blocking collection to browse in the debugger. - - - Returns a snapshot of the underlying collection's elements. - - - - Represents an thread-safe, unordered collection of objects. - - Specifies the type of elements in the bag. - - - Bags are useful for storing objects when ordering doesn't matter, and unlike sets, bags support - duplicates. is a thread-safe bag implementation, optimized for - scenarios where the same thread will be both producing and consuming data stored in the bag. - - - accepts null reference (Nothing in Visual Basic) as a valid - value for reference types. - - - All public and protected members of are thread-safe and may be used - concurrently from multiple threads. - - - - - - Initializes a new instance of the - class. - - - - - Initializes a new instance of the - class that contains elements copied from the specified collection. - - The collection whose elements are copied to the new . - is a null reference - (Nothing in Visual Basic). - - - - Local helper function to initalize a new bag object - - An enumeration containing items with which to initialize this bag. - - - - Adds an object to the . - - The object to be added to the - . The value can be a null reference - (Nothing in Visual Basic) for reference types. - - - - - - - - - - Attempts to add an object to the . - - The object to be added to the - . The value can be a null reference - (Nothing in Visual Basic) for reference types. - Always returns true - - - - Attempts to remove and return an object from the . - - When this method returns, contains the object - removed from the or the default value - of if the operation failed. - true if an object was removed successfully; otherwise, false. - - - - Attempts to return an object from the - without removing it. - - When this method returns, contains an object from - the or the default value of - if the operation failed. - true if and object was returned successfully; otherwise, false. - - - - Local helper function to Take or Peek an item from the bag - - To receive the item retrieved from the bag - True means Take operation, false means Peek operation - True if succeeded, false otherwise - - - - Local helper function to retrieve a thread local list by a thread object - - Create a new list if the thread does ot exist - The local list object - - - - Try to reuse an unowned list if exist - unowned lists are the lists that their owner threads are aborted or terminated - this is workaround to avoid memory leaks. - - The list object, null if all lists are owned - - - - Local helper method to steal an item from any other non empty thread - It enumerate all other threads in two passes first pass acquire the lock with TryEnter if succeeded - it steals the item, otherwise it enumerate them again in 2nd pass and acquire the lock using Enter - - To receive the item retrieved from the bag - Whether to remove or peek. - True if succeeded, false otherwise. - - - - local helper function tries to steal an item from given local list - - - - - Local helper function to check the list if it became empty after acquiring the lock - and wait if there is unsynchronized Add/Take operation in the list to be done - - The list to steal - True if can steal, false otherwise - - - - Copies the elements to an existing - one-dimensional Array, starting at the specified array - index. - - The one-dimensional Array that is the - destination of the elements copied from the - . The Array must have zero-based indexing. - The zero-based index in at which copying - begins. - is a null reference (Nothing in - Visual Basic). - is less than - zero. - is equal to or greater than the - length of the - -or- the number of elements in the source is greater than the available space from - to the end of the destination . - - - - Copies the elements of the to an , starting at a particular - index. - - The one-dimensional Array that is the - destination of the elements copied from the - . The Array must have zero-based indexing. - The zero-based index in at which copying - begins. - is a null reference (Nothing in - Visual Basic). - is less than - zero. - - is multidimensional. -or- - does not have zero-based indexing. -or- - is equal to or greater than the length of the - -or- The number of elements in the source is - greater than the available space from to the end of the destination - . -or- The type of the source cannot be cast automatically to the type of the - destination . - - - - - Copies the elements to a new array. - - A new array containing a snapshot of elements copied from the . - - - - Returns an enumerator that iterates through the . - - An enumerator for the contents of the . - - The enumeration represents a moment-in-time snapshot of the contents - of the bag. It does not reflect any updates to the collection after - was called. The enumerator is safe to use - concurrently with reads from and writes to the bag. - - - - - Returns an enumerator that iterates through the . - - An enumerator for the contents of the . - - The items enumerated represent a moment-in-time snapshot of the contents - of the bag. It does not reflect any update to the collection after - was called. - - - - - Get the data array to be serialized - - - - - Construct the stack from a previously seiralized one - - - - - Local helper method to freeze all bag operations, it - 1- Acquire the global lock to prevent any other thread to freeze the bag, and also new new thread can be added - to the dictionary - 2- Then Acquire all local lists locks to prevent steal and synchronized operations - 3- Wait for all un-synchronized operations to be done - - Retrieve the lock taken result for the global lock, to be passed to Unfreeze method - - - - Local helper method to unfreeze the bag from a frozen state - - The lock taken result from the Freeze method - - - - local helper method to acquire all local lists locks - - - - - Local helper method to release all local lists locks - - - - - Local helper function to wait all unsynchronized operations - - - - - Local helper function to get the bag count, the caller should call it from Freeze/Unfreeze block - - The current bag count - - - - Local helper function to return the bag item in a list, this is mainly used by CopyTo and ToArray - This is not thread safe, should be called in Freeze/UnFreeze bag block - - List the contains the bag items - - - - Gets the number of elements contained in the . - - The number of elements contained in the . - - The count returned represents a moment-in-time snapshot of the contents - of the bag. It does not reflect any updates to the collection after - was called. - - - - - Gets a value that indicates whether the is empty. - - true if the is empty; otherwise, false. - - - - Gets a value indicating whether access to the is - synchronized with the SyncRoot. - - true if access to the is synchronized - with the SyncRoot; otherwise, false. For , this property always - returns false. - - - - Gets an object that can be used to synchronize access to the . This property is not supported. - - The SyncRoot property is not supported. - - - - A class that represents a node in the lock thread list - - - - - A class that represents the lock thread list - - - - - ThreadLocalList constructor - - The owner thread for this list - - - - Add new item to head of the list - - The item to add. - Whether to update the count. - - - - Remove an item from the head of the list - - The removed item - - - - Peek an item from the head of the list - - the peeked item - True if succeeded, false otherwise - - - - Steal an item from the tail of the list - - the removed item - remove or peek flag - - - - Gets the total list count, it's not thread safe, may provide incorrect count if it is called concurrently - - - - - List operations - - - - - A simple class for the debugger view window - - - - - Provides a set of methods for querying objects that implement - ParallelQuery{TSource}. This is the parallel equivalent of - . - - - - - Enables parallelization of a query. - - The type of elements of . - An - to convert to a . - The source as a to bind to - ParallelEnumerable extension methods. - - is a null reference (Nothing in Visual Basic). - - - - - Enables parallelization of a query, as sourced by a partitioner - responsible for splitting the input sequence into partitions. - - The type of elements of . - A partitioner over the input sequence. - The as a ParallelQuery to bind to ParallelEnumerable extension methods. - - The source partitioner's GetOrderedPartitions method is used when ordering is enabled, - whereas the partitioner's GetPartitions is used if ordering is not enabled (the default). - The source partitioner's GetDynamicPartitions and GetDynamicOrderedPartitions are not used. - - - is a null reference (Nothing in Visual Basic). - - - - - Enables treatment of a data source as if it was ordered, overriding the default of unordered. - AsOrdered may only be invoked on sequences returned by AsParallel, ParallelEnumerable.Range, - and ParallelEnumerable.Repeat. - - The type of elements of . - The input sequence. - - Thrown if is not one of AsParallel, ParallelEnumerable.Range, or ParallelEnumerable.Repeat. - - - is a null reference (Nothing in Visual Basic). - - - A natural tension exists between performance and preserving order in parallel processing. By default, - a parallelized query behaves as if the ordering of the results is arbitrary - unless AsOrdered is applied or there is an explicit OrderBy operator in the query. - - The source sequence which will maintain ordering in the query. - - - - Enables treatment of a data source as if it was ordered, overriding the default of unordered. - AsOrdered may only be invoked on sequences returned by AsParallel, ParallelEnumerable.Range, - and ParallelEnumerable.Repeat. - - The input sequence. - - Thrown if the is not one of AsParallel, ParallelEnumerable.Range, or ParallelEnumerable.Repeat. - - - is a null reference (Nothing in Visual Basic). - - - A natural tension exists between performance and preserving order in parallel processing. By default, - a parallelized query behaves as if the ordering of the results is arbitrary unless AsOrdered - is applied or there is an explicit OrderBy operator in the query. - - The source sequence which will maintain ordering in the query. - - - - Allows an intermediate query to be treated as if no ordering is implied among the elements. - - - AsUnordered may provide - performance benefits when ordering is not required in a portion of a query. - - The type of elements of . - The input sequence. - The source sequence with arbitrary order. - - is a null reference (Nothing in Visual Basic). - - - - - Enables parallelization of a query. - - An to convert - to a . - - The source as a ParallelQuery to bind to - ParallelEnumerable extension methods. - - - is a null reference (Nothing in Visual Basic). - - - - - Converts a into an - to force sequential - evaluation of the query. - - The type of elements of . - A to convert to an . - The source as an - to bind to sequential extension methods. - - is a null reference (Nothing in Visual Basic). - - - - - Sets the task scheduler to execute the query. - - The type of elements of . - A ParallelQuery on which to set the task scheduler option. - Task scheduler to execute the query. - ParallelQuery representing the same query as source, but with the task scheduler option set. - - or is a null reference (Nothing in Visual Basic). - - - WithTaskScheduler is used multiple times in the query. - - - - - Sets the degree of parallelism to use in a query. Degree of parallelism is the maximum number of concurrently - executing tasks that will be used to process the query. - - The type of elements of . - A ParallelQuery on which to set the limit on the degrees of parallelism. - The degree of parallelism for the query. - ParallelQuery representing the same query as source, with the limit on the degrees of parallelism set. - - is a null reference (Nothing in Visual Basic). - - - WithDegreeOfParallelism is used multiple times in the query. - - - is less than 1 or greater than 63. - - - - - Sets the to associate with the query. - - The type of elements of . - A ParallelQuery on which to set the option. - A cancellation token. - ParallelQuery representing the same query as source, but with the - registered. - - is a null reference (Nothing in Visual Basic). - - - WithCancellation is used multiple times in the query. - - - The associated with the has been disposed. - - - - - Sets the execution mode of the query. - - The type of elements of . - A ParallelQuery on which to set the option. - The mode in which to execute the query. - ParallelQuery representing the same query as source, but with the - registered. - - is a null reference (Nothing in Visual Basic). - - - is not a valid value. - - - WithExecutionMode is used multiple times in the query. - - - - - Sets the merge options for this query, which specify how the query will buffer output. - - The type of elements of . - A ParallelQuery on which to set the option. - The merge optiosn to set for this query. - ParallelQuery representing the same query as source, but with the - registered. - - is a null reference (Nothing in Visual Basic). - - - is not a valid value. - - - WithMergeOptions is used multiple times in the query. - - - - - Generates a parallel sequence of integral numbers within a specified range. - - The value of the first integer in the sequence. - The number of sequential integers to generate. - An IEnumerable<Int32> in C# or IEnumerable(Of Int32) in - Visual Basic that contains a range of sequential integral numbers. - - is less than 0 - -or- - + - 1 is larger than . - - - - - Generates a parallel sequence that contains one repeated value. - - The type of the value to be repeated in the result sequence. - The value to be repeated. - The number of times to repeat the value in the generated sequence. - A sequence that contains a repeated value. - - is less than 0. - - - - - Returns an empty ParallelQuery{TResult} that has the specified type argument. - - The type to assign to the type parameter of the returned - generic sequence. - An empty sequence whose type argument is . - - - - Invokes in parallel the specified action for each element in the . - - - This is an efficient way to process the output from a parallelized query because it does - not require a merge step at the end. However, order of execution is non-deterministic. - - The type of elements of . - The whose elements will be processed by - . - An Action to invoke on each element. - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Filters in parallel a sequence of values based on a predicate. - - The type of the elements of source. - A sequence to filter. - A function to test each element for a condition. - A sequence that contains elements from the input sequence that satisfy - the condition. - - or is a null reference (Nothing in Visual Basic). - - - - - Filters in parallel a sequence of values based on a predicate. Each element's index is used in the logic of the predicate function. - - The type of the elements of source. - A sequence to filter. - A function to test each element for a condition. - A sequence that contains elements from the input sequence that satisfy the condition. - - or is a null reference (Nothing in Visual Basic). - - - - - Projects in parallel each element of a sequence into a new form. - - The type of the elements of . - The type of elements resturned by selector. - A sequence of values to invoke a transform function on. - A transform function to apply to each element. - A sequence whose elements are the result of invoking the transform function on each - element of . - - or is a null reference (Nothing in Visual Basic). - - - - - Projects in parallel each element of a sequence into a new form by incorporating the element's index. - - The type of the elements of . - The type of elements resturned by selector. - A sequence of values to invoke a transform function on. - A transform function to apply to each element. - A sequence whose elements are the result of invoking the transform function on each - element of . - - or is a null reference (Nothing in Visual Basic). - - - - - Merges in parallel two sequences by using the specified predicate function. - - The type of the elements of the first sequence. - The type of the elements of the second sequence. - The type of the return elements. - The first sequence to zip. - The second sequence to zip. - A function to create a result element from two matching elements. - - A sequence that has elements of type that are obtained by performing - resultSelector pairwise on two sequences. If the sequence lengths are unequal, this truncates - to the length of the shorter sequence. - - - or or is a null reference (Nothing in Visual Basic). - - - - - This Zip overload should never be called. - This method is marked as obsolete and always throws - when invoked. - - This type parameter is not used. - This type parameter is not used. - This type parameter is not used. - This parameter is not used. - This parameter is not used. - This parameter is not used. - This overload always throws a . - The exception that occurs when this method is called. - - This overload exists to disallow usage of Zip with a left data source of type - and a right data source of type . - Otherwise, the Zip operator would appear to be bind to the parallel implementation, but would in reality bind to the sequential implementation. - - - - - Correlates in parallel the elements of two sequences based on matching keys. - The default equality comparer is used to compare keys. - - The type of the elements of the first sequence. - The type of the elements of the second sequence. - The type of the keys returned by the key selector functions. - The type of the result elements. - The first sequence to join. - The sequence to join to the first sequence. - A function to extract the join key from each element of - the first sequence. - A function to extract the join key from each element of - the second sequence. - A function to create a result element from two matching elements. - A sequence that has elements of type that are obtained by performing - an inner join on two sequences. - - or or or - or is a null reference (Nothing in Visual Basic). - - - - - This Join overload should never be called. - This method is marked as obsolete and always throws when invoked. - - This type parameter is not used. - This type parameter is not used. - This type parameter is not used. - This type parameter is not used. - This parameter is not used. - This parameter is not used. - This parameter is not used. - This parameter is not used. - This parameter is not used. - This overload always throws a . - The exception that occurs when this method is called. - - This overload exists to disallow usage Join with a left data source of type - and a right data source of type . - Otherwise, the Join operator would appear to be binding to the parallel implementation, but would in reality bind to the sequential implementation. - - - - - Correlates in parallel the elements of two sequences based on matching keys. - A specified IEqualityComparer{T} is used to compare keys. - - The type of the elements of the first sequence. - The type of the elements of the second sequence. - The type of the keys returned by the key selector functions. - The type of the result elements. - The first sequence to join. - The sequence to join to the first sequence. - A function to extract the join key from each element - of the first sequence. - A function to extract the join key from each element - of the second sequence. - A function to create a result element from two matching elements. - An IEqualityComparer<(Of <(T>)>) to hash and compare keys. - A sequence that has elements of type that are obtained by performing - an inner join on two sequences. - - or or or - or is a null reference (Nothing in Visual Basic). - - - - - This Join overload should never be called. - This method is marked as obsolete and always throws when invoked. - - This type parameter is not used. - This type parameter is not used. - This type parameter is not used. - This type parameter is not used. - This parameter is not used. - This parameter is not used. - This parameter is not used. - This parameter is not used. - This parameter is not used. - This parameter is not used. - This overload always throws a . - The exception that occurs when this method is called. - - This overload exists to disallow usage of Join with a left data source of type - and a right data source of type . - Otherwise, the Join operator would appear to be binding to the parallel implementation, but would in reality bind to the sequential implementation. - - - - - Correlates in parallel the elements of two sequences based on equality of keys and groups the results. - The default equality comparer is used to compare keys. - - The type of the elements of the first sequence. - The type of the elements of the second sequence. - The type of the keys returned by the key selector functions. - The type of the result elements. - The first sequence to join. - The sequence to join to the first sequence. - A function to extract the join key from each element - of the first sequence. - A function to extract the join key from each element - of the second sequence. - A function to create a result element from an element from - the first sequence and a collection of matching elements from the second sequence. - A sequence that has elements of type that are obtained by performing - a grouped join on two sequences. - - or or or - or is a null reference (Nothing in Visual Basic). - - - - - This GroupJoin overload should never be called. - This method is marked as obsolete and always throws when called. - - This type parameter is not used. - This type parameter is not used. - This type parameter is not used. - This type parameter is not used. - This parameter is not used. - This parameter is not used. - This parameter is not used. - This parameter is not used. - This parameter is not used. - This overload always throws a . - The exception that occurs when this method is called. - - This overload exists to disallow usage of GroupJoin with a left data source of type - and a right data source of type . - Otherwise, the GroupJoin operator would appear to be binding to the parallel implementation, - but would in reality bind to the sequential implementation. - - - - - Correlates in parallel the elements of two sequences based on key equality and groups the results. - A specified IEqualityComparer{T} is used to compare keys. - - The type of the elements of the first sequence. - The type of the elements of the second sequence. - The type of the keys returned by the key selector functions. - The type of the result elements. - The first sequence to join. - The sequence to join to the first sequence. - A function to extract the join key from each element - of the first sequence. - A function to extract the join key from each element - of the second sequence. - A function to create a result element from an element from - the first sequence and a collection of matching elements from the second sequence. - An IEqualityComparer<(Of <(T>)>) to hash and compare keys. - A sequence that has elements of type that are obtained by performing - a grouped join on two sequences. - - or or or - or is a null reference (Nothing in Visual Basic). - - - - - This GroupJoin overload should never be called. - This method is marked as obsolete and always throws when called. - - This type parameter is not used. - This type parameter is not used. - This type parameter is not used. - This type parameter is not used. - This parameter is not used. - This parameter is not used. - This parameter is not used. - This parameter is not used. - This parameter is not used. - This parameter is not used. - This overload always throws a . - The exception that occurs when this method is called. - - This overload exists to disallow usage of GroupJoin with a left data source of type - and a right data source of type . - Otherwise, the GroupJoin operator would appear to be binding to the parallel implementation, - but would in reality bind to the sequential implementation. - - - - - Projects in parallel each element of a sequence to an IEnumerable{T} - and flattens the resulting sequences into one sequence. - - The type of elements of . - The type of the elements of the sequence returned by selector. - A sequence of values to project. - A transform function to apply to each element. - A sequence whose elements are the result of invoking the one-to-many transform - function on each element of the input sequence. - - or is a null reference (Nothing in Visual Basic). - - - - - Projects in parallel each element of a sequence to an IEnumerable{T}, and flattens the resulting - sequences into one sequence. The index of each source element is used in the projected form of - that element. - - The type of elements of . - The type of the elements of the sequence returned by selector. - A sequence of values to project. - A transform function to apply to each element. - A sequence whose elements are the result of invoking the one-to-many transform - function on each element of the input sequence. - - or is a null reference (Nothing in Visual Basic). - - - - - Projects each element of a sequence to an IEnumerable{T}, - flattens the resulting sequences into one sequence, and invokes a result selector - function on each element therein. - - The type of elements of . - The type of the intermediate elements collected by . - - A sequence of values to project. - A transform function to apply to each source element; - the second parameter of the function represents the index of the source element. - A function to create a result element from an element from - the first sequence and a collection of matching elements from the second sequence. - A sequence whose elements are the result of invoking the one-to-many transform - function on each element of and then mapping - each of those sequence elements and their corresponding source element to a result element. - - or or - is a null reference (Nothing in Visual Basic). - - - - - Projects each element of a sequence to an IEnumerable{T}, flattens the resulting - sequences into one sequence, and invokes a result selector function on each element - therein. The index of each source element is used in the intermediate projected - form of that element. - - The type of elements of . - The type of the intermediate elements collected by - . - The type of elements to return. - A sequence of values to project. - A transform function to apply to each source element; - the second parameter of the function represents the index of the source element. - A function to create a result element from an element from - the first sequence and a collection of matching elements from the second sequence. - - A sequence whose elements are the result of invoking the one-to-many transform - function on each element of and then mapping - each of those sequence elements and their corresponding source element to a - result element. - - - or or - is a null reference (Nothing in Visual Basic). - - - - - Sorts in parallel the elements of a sequence in ascending order according to a key. - - - In contrast to the sequential implementation, this is not a stable sort. - To achieve a stable sort, change a query of the form: - var ordered = source.OrderBy((e) => e.k); - to instead be formed as: - var ordered = source.Select((e,i) => new { E=e, I=i }).OrderBy((v) => v.i).Select((v) => v.e); - - The type of elements of . - The type of the key returned by . - A sequence of values to order. - A function to extract a key from an element. - An OrderedParallelQuery{TSource} whose elements are sorted - according to a key. - - or is a null reference (Nothing in Visual Basic). - - - - - Sorts in parallel the elements of a sequence in ascending order by using a specified comparer. - - - In contrast to the sequential implementation, this is not a stable sort. - See the remarks for OrderBy(ParallelQuery{TSource}, Func{TSource,TKey}) for - an approach to implementing a stable sort. - - The type of elements of . - The type of the key returned by . - A sequence of values to order. - A function to extract a key from an element. - An IComparer{TKey} to compare keys. - An OrderedParallelQuery{TSource} whose elements are sorted according - to a key. - - or is a null reference (Nothing in Visual Basic). - - - - - Sorts in parallel the elements of a sequence in descending order according to a key. - - - In contrast to the sequential implementation, this is not a stable sort. - See the remarks for OrderBy(ParallelQuery{TSource}, Func{TSource,TKey}) for - an approach to implementing a stable sort. - - The type of elements of . - The type of the key returned by . - A sequence of values to order. - A function to extract a key from an element. - An OrderedParallelQuery{TSource} whose elements are sorted - descending according to a key. - - or is a null reference (Nothing in Visual Basic). - - - - - Sorts the elements of a sequence in descending order by using a specified comparer. - - - In contrast to the sequential implementation, this is not a stable sort. - See the remarks for OrderBy(ParallelQuery{TSource}, Func{TSource,TKey}) for - an approach to implementing a stable sort. - - The type of elements of . - The type of the key returned by . - A sequence of values to order. - A function to extract a key from an element. - An IComparer{TKey} to compare keys. - An OrderedParallelQuery{TSource} whose elements are sorted descending - according to a key. - - or is a null reference (Nothing in Visual Basic). - - - - - Performs in parallel a subsequent ordering of the elements in a sequence - in ascending order according to a key. - - - In contrast to the sequential implementation, this is not a stable sort. - See the remarks for OrderBy(ParallelQuery{TSource}, Func{TSource,TKey}) for - an approach to implementing a stable sort. - - The type of elements of . - The type of the key returned by . - An OrderedParallelQuery{TSource} than - contains elements to sort. - A function to extract a key from an element. - An OrderedParallelQuery{TSource} whose elements are - sorted according to a key. - - or is a null reference (Nothing in Visual Basic). - - - - - Performs in parallel a subsequent ordering of the elements in a sequence in - ascending order by using a specified comparer. - - - In contrast to the sequential implementation, this is not a stable sort. - See the remarks for OrderBy(ParallelQuery{TSource}, Func{TSource,TKey}) for - an approach to implementing a stable sort. - - The type of elements of . - The type of the key returned by . - An OrderedParallelQuery{TSource} that contains - elements to sort. - A function to extract a key from an element. - An IComparer{TKey} to compare keys. - An OrderedParallelQuery{TSource} whose elements are sorted - according to a key. - - or is a null reference (Nothing in Visual Basic). - - - - - Performs in parallel a subsequent ordering of the elements in a sequence in - descending order, according to a key. - - - In contrast to the sequential implementation, this is not a stable sort. - See the remarks for OrderBy(ParallelQuery{TSource}, Func{TSource,TKey}) for - an approach to implementing a stable sort. - - The type of elements of . - The type of the key returned by . - An OrderedParallelQuery{TSource} than contains - elements to sort. - A function to extract a key from an element. - An OrderedParallelQuery{TSource} whose elements are sorted - descending according to a key. - - or is a null reference (Nothing in Visual Basic). - - - - - Performs in parallel a subsequent ordering of the elements in a sequence in descending - order by using a specified comparer. - - - In contrast to the sequential implementation, this is not a stable sort. - See the remarks for OrderBy(ParallelQuery{TSource}, Func{TSource,TKey}) for - an approach to implementing a stable sort. - - The type of elements of . - The type of the key returned by . - An OrderedParallelQuery{TSource} than contains - elements to sort. - A function to extract a key from an element. - An IComparer{TKey} to compare keys. - An OrderedParallelQuery{TSource} whose elements are sorted - descending according to a key. - - or is a null reference (Nothing in Visual Basic). - - - - - Groups in parallel the elements of a sequence according to a specified key selector function. - - The type of elements of . - The type of the key returned by . - An OrderedParallelQuery{TSource}than contains - elements to sort. - A function to extract a key from an element. - An OrderedParallelQuery{TSource}whose elements are sorted - descending according to a key. - - - - Groups in parallel the elements of a sequence according to a specified key selector function and compares the keys by using a specified comparer. - - The type of elements of . - The type of the key returned by >. - An OrderedParallelQuery{TSource} than contains - elements to sort. - A function to extract a key from an element. - An IComparer{TSource} to compare keys. - An OrderedParallelQuery{TSource} whose elements are sorted - descending according to a key. - - or is a null reference (Nothing in Visual Basic). - - - - - Groups in parallel the elements of a sequence according to a specified key selector function and - projects the elements for each group by using a specified function. - - The type of elements of . - The type of the key returned by . - The type of the elements in the IGrouping - An OrderedParallelQuery<(Of <(TElement>)>) than contains - elements to sort. - A function to extract a key from an element. - A function to map each source element to an element in an IGrouping. - A ParallelQuery<IGrouping<TKey, TElement>> in C# or - ParallelQuery(Of IGrouping(Of TKey, TElement)) in Visual Basic where each IGrouping - generic object contains a collection of objects of type and a key. - - or or - is a null reference (Nothing in Visual Basic). - - - - - Groups in parallel the elements of a sequence according to a key selector function. - The keys are compared by using a comparer and each group's elements are projected by - using a specified function. - - The type of elements of . - The type of the key returned by . - The type of the elements in the IGrouping - An OrderedParallelQuery{TSource}than contains elements to sort. - A function to extract a key from an element. - A function to map each source element to an element in an IGrouping. - An IComparer{TSource} to compare keys. - - A ParallelQuery{IGrouping{TKey, TElement}} in C# or - ParallelQuery(Of IGrouping(Of TKey, TElement)) in Visual Basic where each IGrouping - generic object contains a collection of objects of type and a key. - - - or or - is a null reference (Nothing in Visual Basic). - - - - - Groups in parallel the elements of a sequence according to a specified - key selector function and creates a result value from each group and its key. - - The type of the elements of . - The type of the key returned by . - The type of the result value returned by . - A sequence whose elements to group. - A function to extract the key for each element. - A function to create a result value from each group. - A collection of elements of type where each element represents a - projection over a group and its key. - - or or - is a null reference (Nothing in Visual Basic). - - - - - Groups in parallel the elements of a sequence according to a specified key selector function - and creates a result value from each group and its key. The keys are compared - by using a specified comparer. - - The type of the elements of . - The type of the key returned by . - The type of the result value returned by . - A sequence whose elements to group. - A function to extract the key for each element. - A function to create a result value from each group. - An IEqualityComparer{TKey} to compare keys. - - An ParallelQuery<IGrouping<TKey, TResult>> in C# or - ParallelQuery(Of IGrouping(Of TKey, TResult)) in Visual Basic where each - IGrouping<(Of <(TKey, TResult>)>) object contains a collection of objects - of type and a key. - - - or or - is a null reference (Nothing in Visual Basic). - - - - - Groups in parallel the elements of a sequence according to a specified key - selector function and creates a result value from each group and its key. - The elements of each group are projected by using a specified function. - - The type of the elements of . - The type of the key returned by . - The type of the elements in each - IGrouping{TKey, TElement}. - The type of the result value returned by . - A sequence whose elements to group. - A function to extract the key for each element. - A function to map each source element to an element in an - IGrouping<TKey, TElement>. - A function to create a result value from each group. - A collection of elements of type where each element represents a - projection over a group and its key. - - or or - or is a null reference (Nothing in Visual Basic). - - - - - Groups the elements of a sequence according to a specified key selector function and - creates a result value from each group and its key. Key values are compared by using a - specified comparer, and the elements of each group are projected by using a specified function. - - The type of the elements of . - The type of the key returned by . - The type of the elements in each - IGrouping{TKey, TElement}. - The type of the result value returned by . - A sequence whose elements to group. - A function to extract the key for each element. - A function to map each source element to an element in an - IGrouping{Key, TElement}. - A function to create a result value from each group. - An IEqualityComparer{TKey} to compare keys. - A collection of elements of type where each element represents a - projection over a group and its key. - - or or - or is a null reference (Nothing in Visual Basic). - - - - - Run an aggregation sequentially. If the user-provided reduction function throws an exception, wrap - it with an AggregateException. - - - - - if true, use the seed provided in the method argument - if false, use the first element of the sequence as the seed instead - - - - - - Applies in parallel an accumulator function over a sequence. - - The type of the elements of . - A sequence to aggregate over. - An accumulator function to be invoked on each element. - The final accumulator value. - - or is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Applies in parallel an accumulator function over a sequence. - The specified seed value is used as the initial accumulator value. - - The type of the elements of . - The type of the accumulator value. - A sequence to aggregate over. - The initial accumulator value. - An accumulator function to be invoked on each element. - The final accumulator value. - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Applies in parallel an accumulator function over a sequence. The specified - seed value is used as the initial accumulator value, and the specified - function is used to select the result value. - - The type of the elements of . - The type of the accumulator value. - The type of the resulting value. - A sequence to aggregate over. - The initial accumulator value. - An accumulator function to be invoked on each element. - A function to transform the final accumulator value - into the result value. - The transformed final accumulator value. - - or or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Applies in parallel an accumulator function over a sequence. This overload is not - available in the sequential implementation. - - - This overload is specific to processing a parallelized query. A parallelized query may - partition the data source sequence into several sub-sequences (partitions). - The is invoked on each element within partitions. - Each partition then yields a single accumulated result. The - is then invoked on the results of each partition to yield a single element. This element is then - transformed by the function. - - The type of the elements of . - The type of the accumulator value. - The type of the resulting value. - A sequence to aggregate over. - The initial accumulator value. - - An accumulator function to be invoked on each element in a partition. - - - An accumulator function to be invoked on the yielded element from each partition. - - - A function to transform the final accumulator value into the result value. - - The transformed final accumulator value. - - or - or or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Applies in parallel an accumulator function over a sequence. This overload is not - available in the sequential implementation. - - - This overload is specific to parallelized queries. A parallelized query may partition the data source sequence - into several sub-sequences (partitions). The is invoked - on each element within partitions. Each partition then yields a single accumulated result. - The - is then invoked on the results of each partition to yield a single element. This element is then - transformed by the function. - - The type of the elements of . - The type of the accumulator value. - The type of the resulting value. - A sequence to aggregate over. - - A function that returns the initial accumulator value. - - - An accumulator function to be invoked on each element in a partition. - - - An accumulator function to be invoked on the yielded element from each partition. - - - A function to transform the final accumulator value into the result value. - - The transformed final accumulator value. - - or or - or or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the number of elements in a parallel sequence. - - The type of the elements of . - A sequence that contains elements to be counted. - The number of elements in the input sequence. - - is a null reference (Nothing in Visual Basic). - - - The number of elements in source is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns a number that represents how many elements in the specified - parallel sequence satisfy a condition. - - The type of the elements of . - A sequence that contains elements to be counted. - A function to test each element for a condition. - - A number that represents how many elements in the sequence satisfy the condition - in the predicate function. - - - or is a null reference (Nothing in Visual Basic). - - - The number of elements in source is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns an Int64 that represents the total number of elements in a parallel sequence. - - The type of the elements of . - A sequence that contains elements to be counted. - The number of elements in the input sequence. - - is a null reference (Nothing in Visual Basic). - - - The number of elements in source is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns an Int64 that represents how many elements in a parallel sequence satisfy a condition. - - The type of the elements of . - A sequence that contains elements to be counted. - A function to test each element for a condition. - - A number that represents how many elements in the sequence satisfy the condition - in the predicate function. - - - or is a null reference (Nothing in Visual Basic). - - - The number of elements in source is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the sum of a sequence of values. - - A sequence of values to calculate the sum of. - The sum of the values in the sequence. - - is a null reference (Nothing in Visual Basic). - - - The sum is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the sum of a sequence of values. - - A sequence of values to calculate the sum of. - The sum of the values in the sequence. - - is a null reference (Nothing in Visual Basic). - - - The sum is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the sum of a sequence of values. - - A sequence of values to calculate the sum of. - The sum of the values in the sequence. - - is a null reference (Nothing in Visual Basic). - - - The sum is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the sum of a sequence of values. - - A sequence of values to calculate the sum of. - The sum of the values in the sequence. - - is a null reference (Nothing in Visual Basic). - - - The sum is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the sum of a sequence of values. - - A sequence of values to calculate the sum of. - The sum of the values in the sequence. - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the sum of a sequence of values. - - A sequence of values to calculate the sum of. - The sum of the values in the sequence. - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the sum of a sequence of values. - - A sequence of values to calculate the sum of. - The sum of the values in the sequence. - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the sum of a sequence of values. - - A sequence of values to calculate the sum of. - The sum of the values in the sequence. - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the sum of a sequence of values. - - A sequence of values to calculate the sum of. - The sum of the values in the sequence. - - is a null reference (Nothing in Visual Basic). - - - The sum is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the sum of a sequence of values. - - A sequence of values to calculate the sum of. - The sum of the values in the sequence. - - is a null reference (Nothing in Visual Basic). - - - The sum is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the sum of the sequence of values that are obtained - by invoking a transform function on each element of the input sequence. - - A sequence of values to calculate the sum of. - A transform function to apply to each element. - The sum of the values in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - The sum is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the sum of the sequence of values that are obtained - by invoking a transform function on each element of the input sequence. - - The type of elements of . - A sequence of values to calculate the sum of. - A transform function to apply to each element. - The sum of the values in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - The sum is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the sum of the sequence of values that are obtained - by invoking a transform function on each element of the input sequence. - - The type of elements of . - A sequence of values to calculate the sum of. - A transform function to apply to each element. - The sum of the values in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - The sum is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the sum of the sequence of values that are obtained - by invoking a transform function on each element of the input sequence. - - The type of elements of . - A sequence of values to calculate the sum of. - A transform function to apply to each element. - The sum of the values in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - The sum is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the sum of the sequence of values that are obtained - by invoking a transform function on each element of the input sequence. - - The type of elements of . - A sequence of values to calculate the sum of. - A transform function to apply to each element. - The sum of the values in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the sum of the sequence of values that are obtained - by invoking a transform function on each element of the input sequence. - - The type of elements of . - A sequence of values to calculate the sum of. - A transform function to apply to each element. - The sum of the values in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the sum of the sequence of values that are obtained - by invoking a transform function on each element of the input sequence. - - The type of elements of . - A sequence of values to calculate the sum of. - A transform function to apply to each element. - The sum of the values in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the sum of the sequence of values that are obtained - by invoking a transform function on each element of the input sequence. - - The type of elements of . - A sequence of values to calculate the sum of. - A transform function to apply to each element. - The sum of the values in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the sum of the sequence of values that are obtained - by invoking a transform function on each element of the input sequence. - - The type of elements of . - A sequence of values to calculate the sum of. - A transform function to apply to each element. - The sum of the values in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - The sum is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the sum of the sequence of values that are obtained - by invoking a transform function on each element of the input sequence. - - The type of elements of . - A sequence of values to calculate the sum of. - A transform function to apply to each element. - The sum of the values in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - The sum is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the minimum value in a parallel sequence of values. - - A sequence of values to determine the minimum value of. - The minimum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the minimum value in a parallel sequence of values. - - A sequence of values to determine the minimum value of. - The minimum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the minimum value in a parallel sequence of values. - - A sequence of values to determine the minimum value of. - The minimum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the minimum value in a parallel sequence of values. - - A sequence of values to determine the minimum value of. - The minimum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the minimum value in a parallel sequence of values. - - A sequence of values to determine the minimum value of. - The minimum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the minimum value in a parallel sequence of values. - - A sequence of values to determine the minimum value of. - The minimum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the minimum value in a parallel sequence of values. - - A sequence of values to determine the minimum value of. - The minimum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the minimum value in a parallel sequence of values. - - A sequence of values to determine the minimum value of. - The minimum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the minimum value in a parallel sequence of values. - - A sequence of values to determine the minimum value of. - The minimum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the minimum value in a parallel sequence of values. - - A sequence of values to determine the minimum value of. - The minimum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the minimum value in a parallel sequence of values. - - The type of elements of . - A sequence of values to determine the minimum value of. - The minimum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - contains no elements and is a non-nullable value type. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the minimum value. - - The type of elements of . - A sequence of values to determine the minimum value of. - A transform function to apply to each element. - The minimum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the minimum value. - - The type of elements of . - A sequence of values to determine the minimum value of. - A transform function to apply to each element. - The minimum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the minimum value. - - The type of elements of . - A sequence of values to determine the minimum value of. - A transform function to apply to each element. - The minimum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the minimum value. - - The type of elements of . - A sequence of values to determine the minimum value of. - A transform function to apply to each element. - The minimum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the minimum value. - - The type of elements of . - A sequence of values to determine the minimum value of. - A transform function to apply to each element. - The minimum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the minimum value. - - The type of elements of . - A sequence of values to determine the minimum value of. - A transform function to apply to each element. - The minimum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the minimum value. - - The type of elements of . - A sequence of values to determine the minimum value of. - A transform function to apply to each element. - The minimum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the minimum value. - - The type of elements of . - A sequence of values to determine the minimum value of. - A transform function to apply to each element. - The minimum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the minimum value. - - The type of elements of . - A sequence of values to determine the minimum value of. - A transform function to apply to each element. - The minimum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the minimum value. - - The type of elements of . - A sequence of values to determine the minimum value of. - A transform function to apply to each element. - The minimum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the minimum value. - - The type of elements of . - The type of the value returned by . - A sequence of values to determine the minimum value of. - A transform function to apply to each element. - The minimum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - contains no elements and is a non-nullable value type. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the maximum value in a parallel sequence of values. - - A sequence of values to determine the maximum value of. - The maximum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the maximum value in a parallel sequence of values. - - A sequence of values to determine the maximum value of. - The maximum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the maximum value in a parallel sequence of values. - - A sequence of values to determine the maximum value of. - The maximum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the maximum value in a parallel sequence of values. - - A sequence of values to determine the maximum value of. - The maximum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the maximum value in a parallel sequence of values. - - A sequence of values to determine the maximum value of. - The maximum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the maximum value in a parallel sequence of values. - - A sequence of values to determine the maximum value of. - The maximum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the maximum value in a parallel sequence of values. - - A sequence of values to determine the maximum value of. - The maximum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the maximum value in a parallel sequence of values. - - A sequence of values to determine the maximum value of. - The maximum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the maximum value in a parallel sequence of values. - - A sequence of values to determine the maximum value of. - The maximum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the maximum value in a parallel sequence of values. - - A sequence of values to determine the maximum value of. - The maximum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the maximum value in a parallel sequence of values. - - A sequence of values to determine the maximum value of. - The maximum value in the sequence. - - is a null reference (Nothing in Visual Basic). - - - contains no elements and is a non-nullable value type. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the maximum value. - - The type of elements of . - A sequence of values to determine the maximum value of. - A transform function to apply to each element. - The maximum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the maximum value. - - The type of elements of . - A sequence of values to determine the maximum value of. - A transform function to apply to each element. - The maximum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the maximum value. - - The type of elements of . - A sequence of values to determine the maximum value of. - A transform function to apply to each element. - The maximum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the maximum value. - - The type of elements of . - A sequence of values to determine the maximum value of. - A transform function to apply to each element. - The maximum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the maximum value. - - The type of elements of . - A sequence of values to determine the maximum value of. - A transform function to apply to each element. - The maximum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the maximum value. - - The type of elements of . - A sequence of values to determine the maximum value of. - A transform function to apply to each element. - The maximum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the maximum value. - - The type of elements of . - A sequence of values to determine the maximum value of. - A transform function to apply to each element. - The maximum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the maximum value. - - The type of elements of . - A sequence of values to determine the maximum value of. - A transform function to apply to each element. - The maximum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the maximum value. - - The type of elements of . - A sequence of values to determine the maximum value of. - A transform function to apply to each element. - The maximum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the maximum value. - - The type of elements of . - A sequence of values to determine the maximum value of. - A transform function to apply to each element. - The maximum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Invokes in parallel a transform function on each element of a - sequence and returns the maximum value. - - The type of elements of . - The type of the value returned by . - A sequence of values to determine the maximum value of. - A transform function to apply to each element. - The maximum value in the sequence. - - or is a null reference (Nothing in Visual Basic). - - - contains no elements and is a non-nullable value type. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the average of a sequence of values. - - A sequence of values that are used to calculate an average. - The average of the sequence of values. - - is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - The sum or count of the elements in the sequence is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the average of a sequence of values. - - A sequence of values that are used to calculate an average. - The average of the sequence of values. - - is a null reference (Nothing in Visual Basic). - - - The sum or count of the elements in the sequence is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the average of a sequence of values. - - A sequence of values that are used to calculate an average. - The average of the sequence of values. - - is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - The sum or count of the elements in the sequence is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the average of a sequence of values. - - A sequence of values that are used to calculate an average. - The average of the sequence of values. - - is a null reference (Nothing in Visual Basic). - - - The sum or count of the elements in the sequence is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the average of a sequence of values. - - A sequence of values that are used to calculate an average. - The average of the sequence of values. - - is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the average of a sequence of values. - - A sequence of values that are used to calculate an average. - The average of the sequence of values. - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the average of a sequence of values. - - A sequence of values that are used to calculate an average. - The average of the sequence of values. - - is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the average of a sequence of values. - - - A sequence of values that are used to calculate an average. - The average of the sequence of values. - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the average of a sequence of values. - - A sequence of values that are used to calculate an average. - The average of the sequence of values. - - is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the average of a sequence of values. - - A sequence of values that are used to calculate an average. - The average of the sequence of values. - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the average of a sequence of values that are obtained - by invoking a transform function on each element of the input sequence. - - The type of elements of . - A sequence of values that are used to calculate an average. - A transform function to apply to each element. - The average of the sequence of values. - - or is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - The sum or count of the elements in the sequence is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the average of a sequence of values that are obtained - by invoking a transform function on each element of the input sequence. - - The type of elements of . - A sequence of values that are used to calculate an average. - A transform function to apply to each element. - The average of the sequence of values. - - or is a null reference (Nothing in Visual Basic). - - - The sum or count of the elements in the sequence is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the average of a sequence of values that are obtained - by invoking a transform function on each element of the input sequence. - - The type of elements of . - A sequence of values that are used to calculate an average. - A transform function to apply to each element. - The average of the sequence of values. - - or is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - The sum or count of the elements in the sequence is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the average of a sequence of values that are obtained - by invoking a transform function on each element of the input sequence. - - The type of elements of . - A sequence of values that are used to calculate an average. - A transform function to apply to each element. - The average of the sequence of values. - - or is a null reference (Nothing in Visual Basic). - - - The sum or count of the elements in the sequence is larger than . - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the average of a sequence of values that are obtained - by invoking a transform function on each element of the input sequence. - - The type of elements of . - A sequence of values that are used to calculate an average. - A transform function to apply to each element. - The average of the sequence of values. - - or is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the average of a sequence of values that are obtained - by invoking a transform function on each element of the input sequence. - - The type of elements of . - A sequence of values that are used to calculate an average. - A transform function to apply to each element. - The average of the sequence of values. - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the average of a sequence of values that are obtained - by invoking a transform function on each element of the input sequence. - - The type of elements of . - A sequence of values that are used to calculate an average. - A transform function to apply to each element. - The average of the sequence of values. - - or is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the average of a sequence of values that are obtained - by invoking a transform function on each element of the input sequence. - - The type of elements of . - A sequence of values that are used to calculate an average. - A transform function to apply to each element. - The average of the sequence of values. - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the average of a sequence of values that are obtained - by invoking a transform function on each element of the input sequence. - - The type of elements of . - A sequence of values that are used to calculate an average. - A transform function to apply to each element. - The average of the sequence of values. - - or is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Computes in parallel the average of a sequence of values that are obtained - by invoking a transform function on each element of the input sequence. - - The type of elements of . - A sequence of values that are used to calculate an average. - A transform function to apply to each element. - The average of the sequence of values. - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Determines in parallel whether any element of a sequence satisfies a condition. - - The type of elements of . - An IEnumerable whose elements to apply the predicate to. - A function to test each element for a condition. - - true if any elements in the source sequence pass the test in the specified predicate; otherwise, false. - - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Determines whether a parallel sequence contains any elements. - - The type of elements of . - The IEnumerable to check for emptiness. - true if the source sequence contains any elements; otherwise, false. - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Determines in parallel whether all elements of a sequence satisfy a condition. - - The type of elements of . - A sequence whose elements to apply the predicate to. - A function to test each element for a condition. - - true if all elements in the source sequence pass the test in the specified predicate; otherwise, false. - - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Determines in parallel whether a sequence contains a specified element - by using the default equality comparer. - - The type of elements of . - A sequence in which to locate a value. - The value to locate in the sequence. - - true if the source sequence contains an element that has the specified value; otherwise, false. - - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Determines in parallel whether a sequence contains a specified element by using a - specified IEqualityComparer{T}. - - The type of elements of . - A sequence in which to locate a value. - The value to locate in the sequence. - An equality comparer to compare values. - - true if the source sequence contains an element that has the specified value; otherwise, false. - - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns a specified number of contiguous elements from the start of a parallel sequence. - - The type of elements of . - The sequence to return elements from. - The number of elements to return. - - A sequence that contains the specified number of elements from the start of the input sequence. - - - is a null reference (Nothing in Visual Basic). - - - - - Returns elements from a parallel sequence as long as a specified condition is true. - - The type of elements of . - The sequence to return elements from. - A function to test each element for a condition. - - A sequence that contains the elements from the input sequence that occur before - the element at which the test no longer passes. - - - or is a null reference (Nothing in Visual Basic). - - - - - Returns elements from a parallel sequence as long as a specified condition is true. - The element's index is used in the logic of the predicate function. - - The type of elements of . - The sequence to return elements from. - - A function to test each source element for a condition; the second parameter of the - function represents the index of the source element. - - - A sequence that contains elements from the input sequence that occur before - the element at which the test no longer passes. - - - or is a null reference (Nothing in Visual Basic). - - - - - Bypasses a specified number of elements in a parallel sequence and then returns the remaining elements. - - The type of elements of . - The sequence to return elements from. - The number of elements to skip before returning the remaining elements. - - A sequence that contains the elements that occur after the specified index in the input sequence. - - - is a null reference (Nothing in Visual Basic). - - - - - Bypasses elements in a parallel sequence as long as a specified - condition is true and then returns the remaining elements. - - The type of elements of . - The sequence to return elements from. - A function to test each element for a condition. - A sequence that contains the elements from the input sequence starting at - the first element in the linear series that does not pass the test specified by - predicate. - - or is a null reference (Nothing in Visual Basic). - - - - - Bypasses elements in a parallel sequence as long as a specified condition is true and - then returns the remaining elements. The element's index is used in the logic of - the predicate function. - - The type of elements of . - The sequence to return elements from. - - A function to test each source element for a condition; the - second parameter of the function represents the index of the source element. - - - A sequence that contains the elements from the input sequence starting at the - first element in the linear series that does not pass the test specified by - predicate. - - - or is a null reference (Nothing in Visual Basic). - - - - - Concatenates two parallel sequences. - - The type of the elements of the input sequences. - The first sequence to concatenate. - The sequence to concatenate to the first sequence. - A sequence that contains the concatenated elements of the two input sequences. - - or is a null reference (Nothing in Visual Basic). - - - - - This Concat overload should never be called. - This method is marked as obsolete and always throws when called. - - This type parameter is not used. - This parameter is not used. - This parameter is not used. - This overload always throws a . - The exception that occurs when this method is called. - - This overload exists to disallow usage of Concat with a left data source of type - and a right data source of type . - Otherwise, the Concat operator would appear to be binding to the parallel implementation, - but would in reality bind to the sequential implementation. - - - - - Determines whether two parallel sequences are equal by comparing the elements by using - the default equality comparer for their type. - - The type of the elements of the input sequences. - A sequence to compare to second. - A sequence to compare to the first input sequence. - - true if the two source sequences are of equal length and their corresponding elements - are equal according to the default equality comparer for their type; otherwise, false. - - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - This SequenceEqual overload should never be called. - This method is marked as obsolete and always throws when called. - - This type parameter is not used. - This parameter is not used. - This parameter is not used. - This overload always throws a . - Thrown every time this method is called. - - This overload exists to disallow usage of SequenceEqual with a left data source of type - and a right data source of type . - Otherwise, the SequenceEqual operator would appear to be binding to the parallel implementation, - but would in reality bind to the sequential implementation. - - - - - Determines whether two parallel sequences are equal by comparing their elements by - using a specified IEqualityComparer{T}. - - The type of the elements of the input sequences. - A sequence to compare to . - A sequence to compare to the first input sequence. - An IEqualityComparer<(Of <(T>)>) to use to compare elements. - - true if the two source sequences are of equal length and their corresponding - elements are equal according to the default equality comparer for their type; otherwise, false. - - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - A helper method for SequenceEqual to dispose an enumerator. If an exception is thrown by the disposal, - it gets wrapped into an AggregateException, unless it is an OCE with the query's CancellationToken. - - - - - This SequenceEqual overload should never be called. - This method is marked as obsolete and always throws when called. - - This type parameter is not used. - This parameter is not used. - This parameter is not used. - This parameter is not used. - This overload always throws a . - Thrown every time this method is called. - - This overload exists to disallow usage of SequenceEqual with a left data source of type - and a right data source of type . - Otherwise, the SequenceEqual operator would appear to be binding to the parallel implementation, - but would in reality bind to sequential implementation. - - - - - Returns distinct elements from a parallel sequence by using the - default equality comparer to compare values. - - The type of the elements of . - The sequence to remove duplicate elements from. - A sequence that contains distinct elements from the source sequence. - - is a null reference (Nothing in Visual Basic). - - - - - Returns distinct elements from a parallel sequence by using a specified - IEqualityComparer{T} to compare values. - - The type of the elements of . - The sequence to remove duplicate elements from. - An IEqualityComparer<(Of <(T>)>) to compare values. - A sequence that contains distinct elements from the source sequence. - - is a null reference (Nothing in Visual Basic). - - - - - Produces the set union of two parallel sequences by using the default equality comparer. - - The type of the elements of the input sequences. - A sequence whose distinct elements form the first set for the union. - A sequence whose distinct elements form the second set for the union. - A sequence that contains the elements from both input sequences, excluding duplicates. - - or is a null reference (Nothing in Visual Basic). - - - - - This Union overload should never be called. - This method is marked as obsolete and always throws when called. - - This type parameter is not used. - This parameter is not used. - This parameter is not used. - This overload always throws a . - The exception that occurs when this method is called. - - This overload exists to disallow usage of Union with a left data source of type - and a right data source of type . - Otherwise, the Union operator would appear to be binding to the parallel implementation, - but would in reality bind to sequential implementation. - - - - - Produces the set union of two parallel sequences by using a specified IEqualityComparer{T}. - - The type of the elements of the input sequences. - A sequence whose distinct elements form the first set for the union. - A sequence whose distinct elements form the second set for the union. - An IEqualityComparer<(Of <(T>)>) to compare values. - A sequence that contains the elements from both input sequences, excluding duplicates. - - or is a null reference (Nothing in Visual Basic). - - - - - This Union overload should never be called. - This method is marked as obsolete and always throws when called. - - This type parameter is not used. - This parameter is not used. - This parameter is not used. - This parameter is not used. - This overload always throws a . - The exception that occurs when this method is called. - - This overload exists to disallow usage of Union with a left data source of type - and a right data source of type . - Otherwise, the Union operator would appear to be binding to the parallel implementation, - but would in reality bind to the sequential implementation. - - - - - Produces the set intersection of two parallel sequences by using the - default equality comparer to compare values. - - The type of the elements of the input sequences. - A sequence whose distinct elements that also appear in will be returned. - - - A sequence whose distinct elements that also appear in the first sequence will be returned. - - A sequence that contains the elements that form the set intersection of two sequences. - - or is a null reference (Nothing in Visual Basic). - - - - - This Intersect overload should never be called. - This method is marked as obsolete and always throws when called. - - This type parameter is not used. - This parameter is not used. - This parameter is not used. - This overload always throws a . - The exception that occurs when this method is called. - - This overload exists to disallow usage of Intersect with a left data source of type - and a right data source of type . - Otherwise, the Intersect operator would appear to be binding to the parallel implementation, - but would in reality bind to the sequential implementation. - - - - - Produces the set intersection of two parallel sequences by using - the specified IEqualityComparer{T} to compare values. - - The type of the elements of the input sequences. - - A sequence whose distinct elements that also appear in will be returned. - - - A sequence whose distinct elements that also appear in the first sequence will be returned. - - An IEqualityComparer<(Of <(T>)>) to compare values. - A sequence that contains the elements that form the set intersection of two sequences. - - or is a null reference (Nothing in Visual Basic). - - - - - This Intersect overload should never be called. - This method is marked as obsolete and always throws when called. - - This type parameter is not used. - This parameter is not used. - This parameter is not used. - This parameter is not used. - This overload always throws a . - The exception that occurs when this method is called. - - This overload exists to disallow usage of Intersect with a left data source of type - and a right data source of type . - Otherwise, the Intersect operator would appear to be binding to the parallel implementation, - but would in reality bind to the sequential implementation. - - - - - Produces the set difference of two parallel sequences by using - the default equality comparer to compare values. - - The type of the elements of the input sequences. - - A sequence whose elements that are not also in will be returned. - - - A sequence whose elements that also occur in the first sequence will cause those - elements to be removed from the returned sequence. - - A sequence that contains the set difference of the elements of two sequences. - - or is a null reference (Nothing in Visual Basic). - - - - - This Except overload should never be called. - This method is marked as obsolete and always throws when called. - - This type parameter is not used. - This parameter is not used. - This parameter is not used. - This overload always throws a . - The exception that occurs when this method is called. - - This overload exists to disallow usage of Except with a left data source of type - and a right data source of type . - Otherwise, the Except operator would appear to be binding to the parallel implementation, - but would in reality bind to the sequential implementation. - - - - - Produces the set difference of two parallel sequences by using the - specified IEqualityComparer{T} to compare values. - - The type of the elements of the input sequences. - A sequence whose elements that are not also in will be returned. - - A sequence whose elements that also occur in the first sequence will cause those elements - to be removed from the returned sequence. - - An IEqualityComparer<(Of <(T>)>) to compare values. - A sequence that contains the set difference of the elements of two sequences. - - or is a null reference (Nothing in Visual Basic). - - - - - This Except overload should never be called. - This method is marked as obsolete and always throws when called. - - This type parameter is not used. - This parameter is not used. - This parameter is not used. - This parameter is not used. - This overload always throws a . - The exception that occurs when this method is called. - - This overload exists to disallow usage of Except with a left data source of type - and a right data source of type . - Otherwise, the Except operator would appear to be binding to the parallel implementation, - but would in reality bind to the sequential implementation. - - - - - Converts a into an - to force sequential - evaluation of the query. - - The type of the elements of . - The sequence to type as . - The input sequence types as . - - is a null reference (Nothing in Visual Basic). - - - - - Creates an array from a ParallelQuery{T}. - - The type of the elements of . - A sequence to create an array from. - An array that contains the elements from the input sequence. - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Creates a List{T} from an ParallelQuery{T}. - - The type of the elements of . - A sequence to create a List<(Of <(T>)>) from. - A List<(Of <(T>)>) that contains elements from the input sequence. - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Creates a Dictionary{TKey,TValue} from a ParallelQuery{T} according to - a specified key selector function. - - The type of the elements of . - The type of the key returned by . - A sequence to create a Dictionary<(Of <(TKey, TValue>)>) from. - A function to extract a key from each element. - A Dictionary<(Of <(TKey, TValue>)>) that contains keys and values. - - or is a null reference (Nothing in Visual Basic). - - - produces a key that is a null reference (Nothing in Visual Basic). - -or- - produces duplicate keys for two elements. - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Creates a Dictionary{TKey,TValue} from a ParallelQuery{T} according to a - specified key selector function and key comparer. - - The type of the elements of . - The type of the key returned by . - A sequence to create a Dictionary<(Of <(TKey, TValue>)>) from. - A function to extract a key from each element. - An IEqualityComparer<(Of <(T>)>) to compare keys. - A Dictionary<(Of <(TKey, TValue>)>) that contains keys and values. - - or is a null reference (Nothing in Visual Basic). - - - produces a key that is a null reference (Nothing in Visual Basic). - -or- - produces duplicate keys for two elements. - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Creates a Dictionary{TKey,TValue} from a ParallelQuery{T} according to specified - key selector and element selector functions. - - The type of the elements of . - The type of the key returned by . - The type of the value returned by . - A sequence to create a Dictionary<(Of <(TKey, TValue>)>) from. - A function to extract a key from each element. - - A transform function to produce a result element value from each element. - - - A Dictionary<(Of <(TKey, TValue>)>) that contains values of type - selected from the input sequence - - - or or is a null reference (Nothing in Visual Basic). - - - produces a key that is a null reference (Nothing in Visual Basic). - -or- - produces duplicate keys for two elements. - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Creates a Dictionary{TKey,TValue from a ParallelQuery{T} according to a - specified key selector function, a comparer, and an element selector function. - - The type of the elements of . - The type of the key returned by . - The type of the value returned by . - A sequence to create a Dictionary<(Of <(TKey, TValue>)>) from. - A function to extract a key from each element. - A transform function to produce a result element - value from each element. - An IEqualityComparer<(Of <(T>)>) to compare keys. - - A Dictionary<(Of <(TKey, TValue>)>) that contains values of type - selected from the input sequence - - - or or is a null reference (Nothing in Visual Basic). - - - produces a key that is a null reference (Nothing in Visual Basic). - -or- - produces duplicate keys for two elements. - -or- - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Creates an ILookup{TKey,T} from a ParallelQuery{T} according to a specified key selector function. - - The type of elements of . - The type of the key returned by . - The sequence to create a Lookup<(Of <(TKey, TElement>)>) from. - A function to extract a key from each element. - A Lookup<(Of <(TKey, TElement>)>) that contains keys and values. - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Creates an ILookup{TKey,T} from a ParallelQuery{T} according to a specified - key selector function and key comparer. - - The type of elements of . - The type of the key returned by . - The sequence to create a Lookup<(Of <(TKey, TElement>)>) from. - A function to extract a key from each element. - An IEqualityComparer<(Of <(T>)>) to compare keys. - A Lookup<(Of <(TKey, TElement>)>) that contains keys and values. - - or or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Creates an ILookup{TKey,TElement} from a ParallelQuery{T} according to specified - key selector and element selector functions. - - The type of elements of . - The type of the key returned by . - The type of the value returned by . - The sequence to create a Lookup<(Of <(TKey, TElement>)>) from. - A function to extract a key from each element. - - A transform function to produce a result element value from each element. - - - A Lookup<(Of <(TKey, TElement>)>) that contains values of type TElement - selected from the input sequence. - - - or or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Creates an ILookup{TKey,TElement} from a ParallelQuery{T} according to - a specified key selector function, a comparer and an element selector function. - - The type of elements of . - The type of the key returned by . - The type of the value returned by . - The sequence to create a Lookup<(Of <(TKey, TElement>)>) from. - A function to extract a key from each element. - - A transform function to produce a result element value from each element. - - An IEqualityComparer<(Of <(T>)>) to compare keys. - - A Lookup<(Of <(TKey, TElement>)>) that contains values of type TElement selected - from the input sequence. - - - or or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Inverts the order of the elements in a parallel sequence. - - The type of the elements of . - A sequence of values to reverse. - A sequence whose elements correspond to those of the input sequence in reverse order. - - is a null reference (Nothing in Visual Basic). - - - - - Filters the elements of a ParallelQuery based on a specified type. - - The type to filter the elements of the sequence on. - The sequence whose elements to filter. - A sequence that contains elements from the input sequence of type . - - is a null reference (Nothing in Visual Basic). - - - - - Converts the elements of a ParallelQuery to the specified type. - - The type to convert the elements of to. - The sequence that contains the elements to be converted. - - A sequence that contains each element of the source sequence converted to the specified type. - - - is a null reference (Nothing in Visual Basic). - - - - - Returns the first element of a parallel sequence. - The type of the elements of . - The sequence to return the first element of. - The first element in the specified sequence. - - is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the first element in a parallel sequence that satisfies a specified condition. - - There's a temporary difference from LINQ to Objects, this does not throw - ArgumentNullException when the predicate is null. - The type of the elements of . - The sequence to return an element from. - A function to test each element for a condition. - The first element in the sequence that passes the test in the specified predicate function. - - or is a null reference (Nothing in Visual Basic). - - - No element in satisfies the condition in . - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the first element of a parallel sequence, or a default value if the - sequence contains no elements. - - The type of the elements of . - The sequence to return the first element of. - - default(TSource) if is empty; otherwise, the first element in . - - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the first element of the parallel sequence that satisfies a condition or a - default value if no such element is found. - - There's a temporary difference from LINQ to Objects, this does not throw - ArgumentNullException when the predicate is null. - The type of the elements of . - The sequence to return an element from. - A function to test each element for a condition. - - default(TSource) if is empty or if no element passes the test - specified by predicate; otherwise, the first element in that - passes the test specified by predicate. - - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the last element of a parallel sequence. - The type of the elements of . - The sequence to return the last element from. - The value at the last position in the source sequence. - - is a null reference (Nothing in Visual Basic). - - - contains no elements. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the last element of a parallel sequence that satisfies a specified condition. - - The type of the elements of . - The sequence to return an element from. - A function to test each element for a condition. - - The last element in the sequence that passes the test in the specified predicate function. - - - or is a null reference (Nothing in Visual Basic). - - - No element in satisfies the condition in . - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the last element of a parallel sequence, or a default value if the - sequence contains no elements. - - The type of the elements of . - The sequence to return an element from. - - default() if the source sequence is empty; otherwise, the last element in the sequence. - - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the last element of a parallel sequence that satisfies a condition, or - a default value if no such element is found. - - The type of the elements of . - The sequence to return an element from. - A function to test each element for a condition. - - default() if the sequence is empty or if no elements pass the test in the - predicate function; otherwise, the last element that passes the test in the predicate function. - - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the only element of a parallel sequence, and throws an exception if there is not - exactly one element in the sequence. - - The type of the elements of . - The sequence to return the single element of. - The single element of the input sequence. - - is a null reference (Nothing in Visual Basic). - - - The input sequence contains more than one element. -or- The input sequence is empty. - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the only element of a parallel sequence that satisfies a specified condition, - and throws an exception if more than one such element exists. - - The type of the elements of . - The sequence to return the single element of. - A function to test an element for a condition. - The single element of the input sequence that satisfies a condition. - - or is a null reference (Nothing in Visual Basic). - - - No element satisfies the condition in . -or- More than one element satisfies the condition in . - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the only element of a parallel sequence, or a default value if the sequence is - empty; this method throws an exception if there is more than one element in the sequence. - - The type of the elements of . - The sequence to return the single element of. - - The single element of the input sequence, or default() if the - sequence contains no elements. - - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the only element of a parallel sequence that satisfies a specified condition - or a default value if no such element exists; this method throws an exception - if more than one element satisfies the condition. - - The type of the elements of . - The sequence to return the single element of. - A function to test an element for a condition. - - The single element of the input sequence that satisfies the condition, or - default() if no such element is found. - - - or is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the elements of the specified parallel sequence or the type parameter's - default value in a singleton collection if the sequence is empty. - - The type of the elements of . - The sequence to return a default value for if it is empty. - - A sequence that contains default(TSource) if is empty; otherwise, . - - - is a null reference (Nothing in Visual Basic). - - - - - Returns the elements of the specified parallel sequence or the specified value - in a singleton collection if the sequence is empty. - - The type of the elements of . - The sequence to return the specified value for if it is empty. - The value to return if the sequence is empty. - - A sequence that contains defaultValue if is empty; otherwise, . - - - is a null reference (Nothing in Visual Basic). - - - - - Returns the element at a specified index in a parallel sequence. - - The type of the elements of . - A sequence to return an element from. - The zero-based index of the element to retrieve. - The element at the specified position in the source sequence. - - is a null reference (Nothing in Visual Basic). - - - is less than 0 or greater than or equal to the number of elements in . - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Returns the element at a specified index in a parallel sequence or a default value if the - index is out of range. - - The type of the elements of . - A sequence to return an element from. - The zero-based index of the element to retrieve. - - default(TSource) if the index is outside the bounds of the source sequence; - otherwise, the element at the specified position in the source sequence. - - - is a null reference (Nothing in Visual Basic). - - - One or more exceptions occurred during the evaluation of the query. - - - The query was canceled. - - - - - Specifies the preferred type of output merge to use in a query. This is a hint only, and may not be - respected by the system when parallelizing all queries. - - - - Use NotBuffered for queries that will be consumed and output as streams, this has the lowest latency - between beginning query execution and elements being yielded. For some queries, such as those involving a - sort (OrderBy, OrderByDescending), buffering is essential and a hint of NotBuffered or AutoBuffered will - be ignored. - - - Use AutoBuffered for most cases; this is the default. It strikes a balance between latency and - overall performance. - - - Use FullyBuffered for queries when the entire output can be processed before the information is - needed. This option offers the best performance when all of the output can be accumulated before yielding - any information, though it is not suitable for stream processing or showing partial results mid-query. - - - - - - Use the default merge type, which is AutoBuffered. - - - - - Use a merge without output buffers. As soon as result elements have been computed, - make that element available to the consumer of the query. - - - - - Use a merge with output buffers of a size chosen by the system. Results - will accumulate into an output buffer before they are available to the consumer of - the query. - - - - - Use a merge with full output buffers. The system will accumulate all of the - results before making any of them available to the consumer of the query. - - - - - This is a bounded channel meant for single-producer/single-consumer scenarios. - - Specifies the type of data in the channel. - - - - The simplest channel is one that has no synchronization. This is used for stop- - and-go productions where we are guaranteed the consumer is not running - concurrently. It just wraps a FIFO queue internally. - - Assumptions: - Producers and consumers never try to enqueue/dequeue concurrently. - - - - - - We occassionally need a no-op enumerator to stand-in when we don't have data left - within a partition's data stream. These are simple enumerable and enumerator - implementations that always and consistently yield no elements. - - - - - - Represents a parallel sequence. - - - - - Represents a parallel sequence. - - - - - Returns an enumerator that iterates through the sequence. - - An enumerator that iterates through the sequence. - - - - Returns an enumerator that iterates through the sequence. - - An enumerator that iterates through the sequence. - - - - A common enumerator type that unifies all query operator enumerators. - - - - - - - A simple implementation of the IEnumerable{object} interface which wraps - a weakly typed IEnumerable object, allowing it to be accessed as a strongly typed - IEnumerable{object}. - - - - - - An interface that allows developers to specify their own partitioning routines. - - - - - - - A simple implementation of the ParallelQuery{object} interface which wraps an - underlying IEnumerable, such that it can be used in parallel queries. - - - - - A simple implementation of the ParallelQuery{T} interface which wraps an - underlying IEnumerable{T}, such that it can be used in parallel queries. - - - - - - An enum to specify whether an aggregate operator is associative, commutative, - neither, or both. This influences query analysis and execution: associative - aggregations can run in parallel, whereas non-associative cannot; non-commutative - aggregations must be run over data in input-order. - - - - - A simple enumerable type that implements the range algorithm. It also supports - partitioning of the indices by implementing an interface that PLINQ recognizes. - - - - - A simple enumerable type that implements the repeat algorithm. It also supports - partitioning of the count space by implementing an interface that PLINQ recognizes. - - - - - - A special merge helper for indexible queries. Given an indexible query, we know how many elements - we'll have in the result set, so we can allocate the array ahead of time. Then, as each result element - is produced, we can directly insert it into the appropriate position in the output array, paying - no extra cost for ordering. - - - - - - Used as a stand-in for replaceable merge algorithms. Alternative implementations - are chosen based on the style of merge required. - - - - - - Instantiates the array merge helper. - - The query settings - The query results - - - - A method used as a delegate passed into the ForAll operator - - - - - Schedules execution of the merge itself. - - - - - Gets the enumerator over the results. - - We never expect this method to be called. ArrayMergeHelper is intended to be used when we want - to consume the results using GetResultsAsArray(). - - - - - Returns the merged results as an array. - - - - - - An enumerator that merges multiple one-to-one channels into a single output - stream, including any necessary blocking and synchronization. This is an - asynchronous enumerator, i.e. the producers may be inserting items into the - channels concurrently with the consumer taking items out of them. Therefore, - enumerating this object can cause the current thread to block. - - We use a biased choice algorithm to choose from our consumer channels. I.e. we - will prefer to process elements in a fair round-robin fashion, but will - occassionally bypass this if a channel is empty. - - - - - - - Convenience class used by enumerators that merge many partitions into one. - - - - - - WaitAny simulates a Win32-style WaitAny on the set of thin-events. - - An array of thin-events (null elements permitted) - The index of the specific event in events that caused us to wake up. - - - - The default merge helper uses a set of straightforward algorithms for output - merging. Namely, for synchronous merges, the input data is yielded from the - input data streams in "depth first" left-to-right order. For asynchronous merges, - on the other hand, we use a biased choice algorithm to favor input channels in - a "fair" way. No order preservation is carried out by this helper. - - - - - - - Drives execution of an actual merge operation, including creating channel data - structures and scheduling parallel work as appropriate. The algorithms used - internally are parameterized based on the type of data in the partitions; e.g. - if an order preserved stream is found, the merge will automatically use an - order preserving merge, and so forth. - - - - - - The order preserving merge helper guarantees the output stream is in a specific order. This is done - by comparing keys from a set of already-sorted input partitions, and coalescing output data using - incremental key comparisons. - - - - - - - A merge helper that yields results in a streaming fashion, while still ensuring correct output - ordering. This merge only works if each producer task generates outputs in the correct order, - i.e. with an Increasing (or Correct) order index. - - The merge creates DOP producer tasks, each of which will be writing results into a separate - buffer. - - The consumer always waits until each producer buffer contains at least one element. If we don't - have one element from each producer, we cannot yield the next element. (If the order index is - Correct, or in some special cases with the Increasing order, we could yield sooner. The - current algorithm does not take advantage of this.) - - The consumer maintains a producer heap, and uses it to decide which producer should yield the next output - result. After yielding an element from a particular producer, the consumer will take another element - from the same producer. However, if the producer buffer exceeded a particular threshold, the consumer - will take the entire buffer, and give the producer an empty buffer to fill. - - Finally, if the producer notices that its buffer has exceeded an even greater threshold, it will - go to sleep and wait until the consumer takes the entire buffer. - - - - - The initial capacity of the buffer queue. The value was chosen experimentally. - - - - - If the consumer notices that the queue reached this limit, it will take the entire buffer from - the producer, instead of just popping off one result. The value was chosen experimentally. - - - - - If the producer notices that the queue reached this limit, it will go to sleep until woken up - by the consumer. Chosen experimentally. - - - - - Whether the producer is allowed to buffer up elements before handing a chunk to the consumer. - If false, the producer will make each result available to the consumer immediately after it is - produced. - - - - - Buffers for the results. Each buffer has elements added by one producer, and removed - by the consumer. - - - - - Whether each producer is done producing. Set to true by individual producers, read by consumer. - - - - - Whether a particular producer is waiting on the consumer. Read by the consumer, set to true - by producers, set to false by the consumer. - - - - - Whether the consumer is waiting on a particular producer. Read by producers, set to true - by consumer, set to false by producer. - - - - - Each object is a lock protecting the corresponding elements in m_buffers, m_producerDone, - m_producerWaiting and m_consumerWaiting. - - - - - A singleton instance of the comparer used by the producer heap. Eager allocation is OK - because if the static constructor runs, we will be using this merge. - - - - - A structure to represent a producer in the producer heap. - - - - - A comparer used by FixedMaxHeap(Of Producer) - - This comparer will be used by max-heap. We want the producer with the smallest MaxKey to - end up in the root of the heap. - - x.MaxKey GREATER_THAN y.MaxKey => x LESS_THAN y => return - - x.MaxKey EQUALS y.MaxKey => x EQUALS y => return 0 - x.MaxKey LESS_THAN y.MaxKey => x GREATER_THAN y => return + - - - - - Enumerator over the results of an order-preserving pipelining merge. - - - - - Merge helper associated with this enumerator - - - - - Heap used to efficiently locate the producer whose result should be consumed next. - For each producer, stores the order index for the next element to be yielded. - - Read and written by the consumer only. - - - - - Stores the next element to be yielded from each producer. We use a separate array - rather than storing this information in the producer heap to keep the Producer struct - small. - - Read and written by the consumer only. - - - - - A private buffer for the consumer. When the size of a producer buffer exceeds a threshold - (STEAL_BUFFER_SIZE), the consumer will take ownership of the entire buffer, and give the - producer a new empty buffer to place results into. - - Read and written by the consumer only. - - - - - Tracks whether MoveNext() has already been called previously. - - - - - Constructor - - - - - Moves the enumerator to the next result, or returns false if there are no more results to yield. - - - - - If the cancellation of the query has been initiated (because one or more producers - encountered exceptions, or because external cancellation token has been set), the method - will tear down the query and rethrow the exception. - - - - - Wait until a producer's buffer is non-empty, or until that producer is done. - - false if there is no element to yield because the producer is done, true otherwise - - - - Looks for an element from a particular producer in the consumer's private buffer. - - - - - Returns the current result - - - - - This enumerator merges multiple input channels into a single output stream. The merging process just - goes from left-to-right, enumerating each channel in succession in its entirety. - Assumptions: - Before enumerating this object, all producers for all channels must have finished enqueueing new - elements. - - - - - - This enumerator handles the actual coordination among partitions required to - accomplish the repartitioning operation, as explained above. - - The kind of elements. - The key used to distribute elements. - The kind of keys found in the source (ignored). - - - - A repartitioning stream must take input data that has already been partitioned and - redistribute its contents based on a new partitioning algorithm. This is accomplished - by making each partition p responsible for redistributing its input data to the - correct destination partition. Some input elements may remain in p, but many will now - belong to a different partition and will need to move. This requires a great deal of - synchronization, but allows threads to repartition data incrementally and in parallel. - Each partition will "pull" data on-demand instead of partitions "pushing" data, which - allows us to reduce some amount of synchronization overhead. - - We currently only offer one form of reparitioning via hashing. This used to be an - abstract base class, but we have eliminated that to get rid of some virtual calls on - hot code paths. Uses a key selection algorithm with mod'ding to determine destination. - - @TODO: @BUG#519: consider adding a bound to the buffers. Unfortunately this can quite easily - lead to deadlock when multiple repartitions are involved. Need a solution. - @TODO: @BUG#504: consider amortizing synchronization overhead by enqueueing/dequeueing in chunks - rather than single elements. Also need to be careful not to introduce deadlock. - - - - - - - - A partitioned stream just partitions some data source using an extensible - partitioning algorithm and exposes a set of N enumerators that are consumed by - their ordinal index [0..N). It is used to build up a set of streaming computations. - At instantiation time, the actual data source to be partitioned is supplied; and - then the caller will layer on top additional enumerators to represent phases in the - computation. Eventually, a merge can then schedule enumeration of all of the - individual partitions in parallel by obtaining references to the individual - partition streams. - - This type has a set of subclasses which implement different partitioning algorithms, - allowing us to easily plug in different partitioning techniques as needed. The type - supports wrapping IEnumerables and IEnumerators alike, with some preference for the - former as many partitioning algorithms are more intelligent for certain data types. - - - - - - - IPartitionedStreamRecipient is essentially a generic action on a partitioned stream, - whose generic type parameter is the type of the order keys in the partitioned stream. - - - - - - This enumerator handles the actual coordination among partitions required to - accomplish the repartitioning operation, as explained above. In addition to that, - it tracks order keys so that order preservation can flow through the enumerator. - - The kind of elements. - The key used to distribute elements. - The kind of keys found in the source. - - - - Contiguous range chunk partitioning attempts to improve data locality by keeping - data close together in the incoming data stream together in the outgoing partitions. - There are really three types of partitions that are used internally: - - 1. If the data source is indexable--like an array or List_T--we can actually - just compute the range indexes and avoid doing any copying whatsoever. Each - "partition" is just an enumerator that will walk some subset of the data. - 2. If the data source has an index (different than being indexable!), we can - turn this into a range scan of the index. We can roughly estimate distribution - and ensure an evenly balanced set of partitions. - @TODO: @BUG#516: we don't have indexes today. We are considering it for the future. - 3. If we can't use 1 or 2, we instead partition "on demand" by chunking the contents - of the source enumerator as they are requested. The unfortunate thing is that - this requires synchronization, since consumers may be running in parallel. We - amortize the cost of this by giving chunks of items when requested instead of - one element at a time. Note that this approach also works for infinite streams. - - In all cases, the caller can request that enumerators walk elements in striped - contiguous chunks. If striping is requested, then each partition j will yield elements - in the data source for which ((i / s)%p) == j, where i is the element's index, s is - a chunk size calculated by the system with the intent of aligning on cache lines, and - p is the number of partitions. If striping is not requested, we use the same algorith, - only, instead of aligning on cache lines, we use a chunk size of l / p, where l - is the length of the input and p is the number of partitions. - - Notes: - This is used as the default partitioning strategy by much of the PLINQ infrastructure. - - - - - - The aggregation operator is a little unique, in that the enumerators it returns - yield intermediate results instead of the final results. That's because there is - one last Aggregate operation that must occur in order to perform the final reduction - over the intermediate streams. In other words, the intermediate enumerators produced - by this operator are never seen by other query operators or consumers directly. - - An aggregation performs parallel prefixing internally. Given a binary operator O, - it will generate intermediate results by folding O across partitions; then it - performs a final reduction by folding O accross the intermediate results. The - analysis engine knows about associativity and commutativity, and will ensure the - style of partitioning inserted into the tree is compatable with the operator. - - For instance, say O is + (meaning it is AC), our input is {1,2,...,8}, and we - use 4 partitions to calculate the aggregation. Sequentially this would look - like this O(O(O(1,2),...),8), in other words ((1+2)+...)+8. The parallel prefix - of this (w/ 4 partitions) instead calculates the intermediate aggregations, i.e.: - t1 = O(1,2), t2 = O(3,4), ... t4 = O(7,8), aka t1 = 1+2, t2 = 3+4, t4 = 7+8. - The final step is to aggregate O over these intermediaries, i.e. - O(O(O(t1,t2),t3),t4), or ((t1+t2)+t3)+t4. This generalizes to any binary operator. - - Beause some aggregations use a different input, intermediate, and output types, - we support an even more generalized aggregation type. In this model, we have - three operators, an intermediate (used for the incremental aggregations), a - final (used for the final summary of intermediate results), and a result selector - (used to perform whatever transformation is needed on the final summary). - - - - - - - - The base class from which all binary query operators derive, that is, those that - have two child operators. This introduces some convenience methods for those - classes, as well as any state common to all subclasses. - - - - - - - This is the abstract base class for all query operators in the system. It - implements the ParallelQuery{T} type so that it can be bound as the source - of parallel queries and so that it can be returned as the result of parallel query - operations. Not much is in here, although it does serve as the "entry point" for - opening all query operators: it will lazily analyze and cache a plan the first - time the tree is opened, and will open the tree upon calls to GetEnumerator. - - Notes: - This class implements ParallelQuery so that any parallel query operator - can bind to the parallel query provider overloads. This allows us to string - together operators w/out the user always specifying AsParallel, e.g. - Select(Where(..., ...), ...), and so forth. - - - - - - The QueryResults{T} is a class representing the results of the query. There may - be different ways the query results can be manipulated. Currently, two ways are - supported: - - 1. Open the query results as a partitioned stream by calling GivePartitionedStream - and pass a generic action as an argument. - - 2. Access individual elements of the results list by calling GetElement(index) and - ElementsCount. This method of accessing the query results is available only if - IsIndexible return true. - - - - - - A QueryOperator that represents the output of the query partitioner.AsParallel(). - - - - - Determines the OrdinalIndexState for a partitioner - - - - - QueryResults for a PartitionerQueryOperator - - - - - Enumerator that converts an enumerator over key-value pairs exposed by a partitioner - to a QueryOperatorEnumerator used by PLINQ internally. - - - - - Enumerator that converts an enumerator over key-value pairs exposed by a partitioner - to a QueryOperatorEnumerator used by PLINQ internally. - - - - - A scan is just a simple operator that is positioned directly on top of some - real data source. It's really just a place holder used during execution and - analysis -- it should never actually get opened. - - - - - - Operator that yields the elements from the first data source that aren't in the second. - This is known as the set relative complement, i.e. left - right. - - - - - - The base class from which all binary query operators derive, that is, those that - have two child operators. This introduces some convenience methods for those - classes, as well as any state common to all subclasses. - - - - - - - - A group join operator takes a left query tree and a right query tree, and then yields - the matching elements between the two. This can be used for outer joins, i.e. those - where an outer element has no matching inner elements -- the result is just an empty - list. As with the join algorithm above, we currently use a hash join algorithm. - - - - - - - - - This enumerator implements the hash-join algorithm as noted earlier. - - Assumptions: - This enumerator type won't work properly at all if the analysis engine didn't - ensure a proper hash-partition. We expect inner and outer elements with equal - keys are ALWAYS in the same partition. If they aren't (e.g. if the analysis is - busted) we'll silently drop items on the floor. :( - - - This is the enumerator class for two operators: - - Join - - GroupJoin - - - - - - - - - - Operator that yields the intersection of two data sources. - - - - - - A join operator takes a left query tree and a right query tree, and then yields the - matching pairs between the two. LINQ supports equi-key-based joins. Hence, a key- - selection function for the left and right data types will yield keys of the same - type for both. We then merely have to match elements from the left with elements from - the right that have the same exact key. Note that this is an inner join. In other - words, outer elements with no matching inner elements do not appear in the output. - - @TODO: @BUG#528: Currently we implement only a hash-join algorithm. Furthermore, we always - choose the inner data source for the hash-table creation. There is room for - optimization and different algorithm choices eventually. - - Hash-joins work in two phases: - - (1) Building - we build a hash-table from one of the data sources. In the case - of this specific operator, the table is built from the hash-codes of - keys selected via the key selector function. Because elements may share - the same key, the table must support one-key-to-many-values. - (2) Probing - for each element in the data source not used for building, we - use its key to look into the hash-table. If we find elements under this - key, we just enumerate all of them, yielding them as join matches. - - Because hash-tables exhibit on average O(1) lookup, we turn what would have been - an O(n*m) algorithm -- in the case of nested loops joins -- into an O(n) algorithm. - We of course require some additional storage to do so, but in general this pays. - - - - - - - - - Operator that yields the union of two data sources. - - - - - - A Zip operator combines two input data sources into a single output stream, - using a pairwise element matching algorithm. For example, the result of zipping - two vectors a = {0, 1, 2, 3} and b = {9, 8, 7, 6} is the vector of pairs, - c = {(0,9), (1,8), (2,7), (3,6)}. Because the expectation is that each element - is matched with the element in the other data source at the same ordinal - position, the zip operator requires order preservation. - - - - - - - - Partitioned stream recipient that will merge the results. - - - - - A wrapper enumerator that just opens the query operator when MoveNext() is called for the - first time. We use QueryOpeningEnumerator to call QueryOperator.GetOpenedEnumerator() - lazily because once GetOpenedEnumerator() is called, PLINQ starts precomputing the - results of the query. - - - - - Opens the query and initializes m_openedQueryEnumerator and m_querySettings. - Called from the first MoveNext call. - - - - - An inlined count aggregation and its enumerator. - - - - - - This class is common to all of the "inlined" versions of various aggregations. The - inlined operators ensure that real MSIL instructions are used to perform elementary - operations versus general purpose delegate-based binary operators. For obvious reasons - this is a quite bit more efficient, although it does lead to a fair bit of unfortunate - code duplication. - - - - - - - - A class with some shared implementation between all aggregation enumerators. - - - - - - An inlined average aggregation operator and its enumerator, for decimals. - - - - - An inlined min/max aggregation and its enumerator, for decimals. - - - - - An inlined sum aggregation and its enumerator, for decimals. - - - - - An inlined average aggregation operator and its enumerator, for doubles. - - - - - An inlined min/max aggregation and its enumerator, for doubles. - - Notes: - Note that normally double.NaN < anything is false, as is anything < NaN. This would - lead to some strangeness in Min and Max, e.g. Min({ NaN, 5.0 } == NaN, yet - Min({ 5.0, NaN }) == 5.0! We impose a total ordering so that NaN is smaller than - everything, including -infinity, which is consistent with Comparer_T. - - - - - An inlined sum aggregation and its enumerator, for doubles. - - - - - An inlined average aggregation operator and its enumerator, for floats. - - - - - An inlined min/max aggregation and its enumerator, for floats. - - - - - An inlined sum aggregation and its enumerator, for floats. - - - - - An inlined average aggregation operator and its enumerator, for ints. - - - - - An inlined min/max aggregation and its enumerator, for ints. - - - - - Inlined aggregations for summing up primitives (int, long, float, double, decimal), as - well as the nullable versions of each (int?, long?, float?, double?, decimal?). - - - - - An inlined average aggregation operator and its enumerator, for longs. - - - - - An inlined count aggregation and its enumerator. - - - - - - An inlined min/max aggregation and its enumerator, for longs. - - - - - An inlined sum aggregation and its enumerator, for longs. - - - - - An inlined average aggregation operator and its enumerator, for Nullable decimals. - - - - - An inlined min/max aggregation and its enumerator, for Nullable decimals. - - - - - An inlined sum aggregation and its enumerator, for nullable decimals. - - - - - An inlined average aggregation operator and its enumerator, for Nullable doubles. - - - - - An inlined min/max aggregation and its enumerator, for Nullable{Double}s. - - Notes: - Note that normally double.NaN < anything is false, as is anything < NaN. This would - lead to some strangeness in Min and Max, e.g. Min({ NaN, 5.0 } == NaN, yet - Min({ 5.0, NaN }) == 5.0! We impose a total ordering so that NaN is smaller than - everything, including -infinity, which is consistent with Comparer_T. - - - - - An inlined sum aggregation and its enumerator, for nullable doubles. - - - - - An inlined average aggregation operator and its enumerator, for Nullable floats. - - - - - An inlined min/max aggregation and its enumerator, for Nullable floats. - - Notes: - Note that normally float.NaN < anything is false, as is anything < NaN. This would - lead to some strangeness in Min and Max, e.g. Min({ NaN, 5.0 } == NaN, yet - Min({ 5.0, NaN }) == 5.0! We impose a total ordering so that NaN is smaller than - everything, including -infinity, which is consistent with Comparer_T. - - - - - An inlined sum aggregation and its enumerator, for Nullable floats. - - - - - An inlined average aggregation operator and its enumerator, for Nullable ints. - - - - - An inlined min/max aggregation and its enumerator, for Nullable ints. - - - - - An inlined sum aggregation and its enumerator, for Nullable ints. - - - - - An inlined average aggregation operator and its enumerator, for Nullable longs. - - - - - An inlined min/max aggregation and its enumerator, for Nullable{Int64}s. - - - - - An inlined sum aggregation and its enumerator, for Nullable longs. - - - - - Class to represent an IList{T} as QueryResults{T} - - - - - - Describes the state of order preservation index associated with an enumerator. - - - - - This type contains query execution options specified by the user. - QuerySettings are used as follows: - - in the query construction phase, some settings may be uninitialized. - - at the start of the query opening phase, the WithDefaults method - is used to initialize all uninitialized settings. - - in the rest of the query opening phase, we assume that all settings - have been initialized. - - - - - Represents operators AsOrdered and AsUnordered. In the current implementation, it - simply turns on preservation globally in the query. - - - - - - Represents operators that set various query execution options. - - - - - - The any/all operators work the same way. They search for the occurrence of a predicate - value in the data source, and upon the first occurrence of such a value, yield a - particular value. Specifically: - - - Any returns true if the predicate for any element evaluates to true. - - All returns false if the predicate for any element evaluates to false. - - This uniformity is used to apply a general purpose algorithm. Both sentences above - take the form of "returns XXX if the predicate for any element evaluates to XXX." - Therefore, we just parameterize on XXX, called the qualifciation below, and if we - ever find an occurrence of XXX in the input data source, we also return XXX. Otherwise, - we return !XXX. Obviously, XXX in this case is a bool. - - This is a search algorithm. So once any single partition finds an element, it will - return so that execution can stop. This is done with a "cancelation" flag that is - polled by all parallel workers. The first worker to find an answer sets it, and all - other workers notice it and quit as quickly as possible. - - - - - - Concatenates one data source with another. Order preservation is used to ensure - the output is actually a concatenation -- i.e. one after the other. The only - special synchronization required is to find the largest index N in the first data - source so that the indices of elements in the second data source can be offset - by adding N+1. This makes it appear to the order preservation infrastructure as - though all elements in the second came after all elements in the first, which is - precisely what we want. - - - - - - Contains is quite similar to the any/all operator above. Each partition searches a - subset of elements for a match, and the first one to find a match signals to the rest - of the partititons to stop searching. - - - - - - This operator just exposes elements directly from the underlying data source, if - it's not empty, or yields a single default element if the data source is empty. - There is a minimal amount of synchronization at the beginning, until all partitions - have registered whether their stream is empty or not. Once the 0th partition knows - that at least one other partition is non-empty, it may proceed. Otherwise, it is - the 0th partition which yields the default value. - - - - - - This operator yields all of the distinct elements in a single data set. It works quite - like the above set operations, with the obvious difference being that it only accepts - a single data source as input. - - - - - - ElementAt just retrieves an element at a specific index. There is some cross-partition - coordination to force partitions to stop looking once a partition has found the - sought-after element. - - - - - - Executes the query, either sequentially or in parallel, depending on the query execution mode and - whether a premature merge was inserted by this ElementAt operator. - - result - withDefaultValue - whether an element with this index exists - - - - First tries to discover the first element in the source, optionally matching a - predicate. All partitions search in parallel, publish the lowest index for a - candidate match, and reach a barrier. Only the partition that "wins" the race, - i.e. who found the candidate with the smallest index, will yield an element. - - - - - - A forall operator just enables an action to be placed at the "top" of a query tree - instead of yielding an enumerator that some consumer can walk. We execute the - query for effect instead of yielding a data result. - - - - - - The operator type for GroupBy statements. This operator groups the input based on - a key-selection routine, yielding one-to-many values of key-to-elements. The - implementation is very much like the hash join operator, in which we first build - a big hashtable of the input; then we just iterate over each unique key in the - hashtable, yielding it plus all of the elements with the same key. - - - - - - - - An ordered version of the grouping data structure. Represents an ordered group of elements that - have the same grouping key. - - - - - Constructs a new grouping - - - - - Add an element - - - - - No more elements will be added, so we can sort the group now. - - - - - The key this grouping represents. - - - - - A variant of the Select operator that supplies element index while performing the - projection operation. This requires cooperation with partitioning and merging to - guarantee ordering is preserved. - - @TODO: @PERF: @BUG#527: as an optimization, we strictly don't need order to be preserved - all the way until the merge. If ordering is only kept for THIS operator, we - can subsequently get rid of order preservation after executing. - - - - - - - A variant of the Where operator that supplies element index while performing the - filtering operation. This requires cooperation with partitioning and merging to - guarantee ordering is preserved. - - @TODO: @PERF: @BUG#527: as an optimization, we strictly don't need order to be preserved - all the way until the merge. If ordering is only kept for THIS operator, we - can subsequently get rid of order preservation after executing. - - - - - - Last tries to discover the last element in the source, optionally matching a - predicate. All partitions search in parallel, publish the greatest index for a - candidate match, and reach a barrier. Only the partition that "wins" the race, - i.e. who found the candidate with the largest index, will yield an element. - - @TODO: @PERF: @BUG#414: this traverses the data source in forward-order. In the future, we - will want to traverse in reverse order, since this allows partitions to stop - the search sooner (by watching if the current index passes below the current best). - - - - - - - Reverse imposes ordinal order preservation. There are normally two phases to this - operator's execution. Each partition first builds a buffer containing all of its - elements, and then proceeds to yielding the elements in reverse. There is a - 'barrier' (but not a blocking barrier) in between these two steps, at which point the largest index becomes - known. This is necessary so that when elements from the buffer are yielded, the - CurrentIndex can be reported as the largest index minus the original index (thereby - reversing the indices as well as the elements themselves). If the largest index is - known a priori, because we have an array for example, we can avoid the barrier in - between the steps. - - - - - - SelectMany is effectively a nested loops join. It is given two data sources, an - outer and an inner -- actually, the inner is sometimes calculated by invoking a - function for each outer element -- and we walk the outer, walking the entire - inner enumerator for each outer element. There is an optional result selector - function which can transform the output before yielding it as a result element. - - Notes: - Although select many takes two enumerable objects as input, it appears to the - query analysis infrastructure as a unary operator. That's because it works a - little differently than the other binary operators: it has to re-open the right - child every time an outer element is walked. The right child is NOT partitioned. - - - - - - - - A helper method for WrapPartitionedStream. We use the helper to reuse a block of code twice, but with - a different order key type. (If premature merge occured, the order key type will be "int". Otherwise, - it will be the same type as "TLeftKey" in WrapPartitionedStream.) - - - - - Similar helper method to WrapPartitionedStreamNotIndexed, except that this one is for the indexed variant - of SelectMany (i.e., the SelectMany that passes indices into the user sequence-generating delegate) - - - - - The operator type for Select statements. This operator transforms elements as it - enumerates them through the use of a selector delegate. - - - - - - - Single searches the input to find the sole element that satisfies the (optional) - predicate. If multiple such elements are found, the caller is responsible for - producing an error. There is some degree of cross-partition synchronization to - proactively hault the search if we ever determine there are multiple elements - satisfying the search in the input. - - - - - - The query operator for OrderBy and ThenBy. - - - - - - - Take and Skip either take or skip a specified number of elements, captured in the - count argument. These will work a little bit like TakeWhile and SkipWhile: there - are two phases, (1) Search and (2) Yield. In the search phase, our goal is to - find the 'count'th index from the input. We do this in parallel by sharing a count- - sized array. Each thread races to populate the array with indices in ascending - order. This requires synchronization for inserts. We use a simple heap, for decent - worst case performance. After a thread has scanned ‘count’ elements, or its current - index is greater than or equal to the maximum index in the array (and the array is - fully populated), the thread can stop searching. All threads issue a barrier before - moving to the Yield phase. When the Yield phase is entered, the count-1th element - of the array contains: in the case of Take, the maximum index (exclusive) to be - returned; or in the case of Skip, the minimum index (inclusive) to be returned. The - Yield phase simply consists of yielding these elements as output. - - - - - - Determines the order index state for the output operator - - - - - Take- and SkipWhile work similarly. Execution is broken into two phases: Search - and Yield. - - During the Search phase, many partitions at once search for the first occurrence - of a false element. As they search, any time a partition finds a false element - whose index is lesser than the current lowest-known false element, the new index - will be published, so other partitions can stop the search. The search stops - as soon as (1) a partition exhausts its input, (2) the predicate yields false for - one of the partition's elements, or (3) its input index passes the current lowest- - known index (sufficient since a given partition's indices are always strictly - incrementing -- asserted below). Elements are buffered during this process. - - Partitions use a barrier after Search and before moving on to Yield. Once all - have passed the barrier, Yielding begins. At this point, the lowest-known false - index will be accurate for the entire set, since all partitions have finished - scanning. This is where TakeWhile and SkipWhile differ. TakeWhile will start at - the beginning of its buffer and yield all elements whose indices are less than - the lowest-known false index. SkipWhile, on the other hand, will skipp any such - elements in the buffer, yielding those whose index is greater than or equal to - the lowest-known false index, and then finish yielding any remaining elements in - its data source (since it may have stopped prematurely due to (3) above). - - - - - - Determines the order index state for the output operator - - - - - The operator type for Where statements. This operator filters out elements that - don't match a filter function (supplied at instantiation time). - - - - - - Poll frequency (number of loops per cancellation check) for situations where per-1-loop testing is too high an overhead. - - - - - Throws an OCE if the merged token has been canceled. - - A token to check for cancelation. - - - - A spooling task handles marshaling data from a producer to a consumer. It simply - takes data from a producer and hands it off to a consumer. This class is the base - class from which other concrete spooling tasks derive, encapsulating some common - logic (such as capturing exceptions). - - - - - Simple abstract task representation, allowing either synchronous and asynchronous - execution. Subclasses override the Work API to implement the logic. - - - - - The number of elements to accumulate on the producer before copying the elements to the - producer-consumer buffer. This constant is only used in the AutoBuffered mode. - - Experimentally, 16 appears to be sufficient buffer size to compensate for the synchronization - cost. - - - - - Whether the producer is allowed to buffer up elements before handing a chunk to the consumer. - If false, the producer will make each result available to the consumer immediately after it is - produced. - - - - - Constructor - - - - - This method is responsible for enumerating results and enqueueing them to - the output buffer as appropriate. Each base class implements its own. - - - - - Creates and begins execution of a new set of spooling tasks. - - - - - Dispose the underlying enumerator and wake up the consumer if necessary. - - - - - A spooling task handles marshaling data from a producer to a consumer. It's given - a single enumerator object that contains all of the production algorithms, a single - destination channel from which consumers draw results, and (optionally) a - synchronization primitive using which to notify asynchronous consumers. This - particular task variant preserves sort order in the final data. - - - - - - - A collection of tasks used by a single query instance. This type also offers some - convenient methods for tracing significant ETW events, waiting on tasks, propagating - exceptions, and performing cancellation activities. - - - - - A factory class to execute spooling logic. - - - - - A spooling task handles marshaling data from a producer to a consumer. It's given - a single enumerator object that contains all of the production algorithms, a single - destination channel from which consumers draw results, and (optionally) a - synchronization primitive using which to notify asynchronous consumers. - - - - - - - A spooling task handles marshaling data from a producer to a consumer. It's given - a single enumerator object that contains all of the production algorithms, a single - destination channel from which consumers draw results, and (optionally) a - synchronization primitive using which to notify asynchronous consumers. - - - - - - - A spooling task handles marshaling data from a producer to a consumer. It's given - a single enumerator object that contains all of the production algorithms, a single - destination channel from which consumers draw results, and (optionally) a - synchronization primitive using which to notify asynchronous consumers. - - - - - - - Wraps an enumerable with a cancellation checker. The enumerator handed out by the source enumerable - will be wrapped by an object that periodically checks whether a particular cancellation token has - been cancelled. If so, the next call to MoveNext() will throw an OperationCancelledException. - - - - - WrapEnumerable.ExceptionAggregator wraps the enumerable with another enumerator that will - catch exceptions, and wrap each with an AggregateException. - - If PLINQ decides to execute a query sequentially, we will reuse LINQ-to-objects - implementations for the different operators. However, we still need to throw - AggregateException in the cases when parallel execution would have thrown an - AggregateException. Thus, we introduce a wrapper enumerator that catches exceptions - and wraps them with an AggregateException. - - - - - A variant of WrapEnumerable that accepts a QueryOperatorEnumerator{,} instead of an IEnumerable{}. - The code duplication is necessary to avoid extra virtual method calls that would otherwise be needed to - convert the QueryOperatorEnumerator{,} to an IEnumerator{}. - - - - - Accepts an exception, wraps it as if it was crossing the parallel->sequential boundary, and throws the - wrapped exception. In sequential fallback cases, we use this method to throw exceptions that are consistent - with exceptions thrown by PLINQ when the query is executed by worker tasks. - - The exception will be wrapped into an AggregateException, except for the case when the query is being - legitimately cancelled, in which case we will propagate the CancellationException with the appropriate - token. - - - - - Wraps a function with a try/catch that morphs all exceptions into AggregateException. - - The input argument type. - The return value type. - A function to use internally. - The cancellation state to use. - A new function containing exception wrapping logic. - - - - ExchangeUtilities is a static class that contains helper functions to partition and merge - streams. - - - - - Used during hash partitioning, when the keys being memoized are not used for anything. - - - - - Very simple heap data structure, of fixed size. - - - - - - A growing array. Unlike List{T}, it makes the internal array available to its user. - - - - - - A simple hash map data structure, derived from the LINQ set we also use. - - The kind of keys contained within. - The kind of values contained within. - - - - A linked list of array chunks. Allows direct access to its arrays. - - The elements held within. - - - - Allocates a new root chunk of a particular size. - - - - - Adds an element to this chunk. Only ever called on the root. - - The new element. - - - - Fetches an enumerator to walk the elements in all chunks rooted from this one. - - - - - The next chunk in the linked chain. - - - - - The number of elements contained within this particular chunk. - - - - - Lookup class implements the ILookup interface. Lookup is very similar to a dictionary - except multiple values are allowed to map to the same key, and null keys are supported. - - Support for null keys adds an issue because the Dictionary class Lookup uses for - storage does not support null keys. So, we need to treat null keys separately. - Unfortunately, since TKey may be a value type, we cannot test whether the key is null - using the user-specified equality comparer. - - C# does allow us to compare the key against null using the == operator, but there is a - possibility that the user's equality comparer considers null to be equal to other values. - Now, MSDN documentation specifies that if IEqualityComparer.Equals(x,y) returns true, it - must be the case that x and y have the same hash code, and null has no hash code. Despite - that, we might as well support the use case, even if it is bad practice. - - The solution the Lookup class uses is to treat the key default(TKey) as a special case, - and hold its associated grouping - if any - in a special field instead of inserting it - into a dictionary. - - - - - - - A pair just wraps two bits of data into a single addressable unit. This is a - value type to ensure it remains very lightweight, since it is frequently used - with other primitive data types as well. - - - - - - - PairComparer compares pairs by the first element, and breaks ties by the second - element. - - - - - - - Comparer that wraps another comparer, and flips the result of each comparison to the - opposite answer. - - - - - - A set for various operations. Shamelessly stolen from LINQ's source code. - @TODO: can the Linq one be used directly now that we are in System.Core - - The kind of elements contained within. - - - - A very simple primitive that allows us to share a value across multiple threads. - - - - - - Common miscellaneous utility methods used throughout the code-base. - - - - - A struct to wrap any arbitrary object reference or struct. Used for situations - where we can't tolerate null values (like keys for hashtables). - - - - - - Compares two wrapped structs of the same underlying type for equality. Simply - wraps the actual comparer for the type being wrapped. - - - - - - Represents a sorted, parallel sequence. - - - - - Returns an enumerator that iterates through the sequence. - - An enumerator that iterates through the sequence. - - - - The query execution mode is a hint that specifies how the system should handle - performance trade-offs when parallelizing queries. - - - - - By default, the system will use algorithms for queries - that are ripe for parallelism and will avoid algorithms with high - overheads that will likely result in slow downs for parallel execution. - - - - - Parallelize the entire query, even if that means using high-overhead algorithms. - - - - - Provides a set of static (Shared in Visual Basic) methods for working with specific kinds of - instances. - - - - - Creates a proxy Task that represents the - asynchronous operation of a Task{Task}. - - - It is often useful to be able to return a Task from a - Task{TResult}, where the inner Task represents work done as part of the outer Task{TResult}. However, - doing so results in a Task{Task}, which, if not dealt with carefully, could produce unexpected behavior. Unwrap - solves this problem by creating a proxy Task that represents the entire asynchronous operation of such a Task{Task}. - - The Task{Task} to unwrap. - The exception that is thrown if the - argument is null. - A Task that represents the asynchronous operation of the provided Task{Task}. - - - - Creates a proxy Task{TResult} that represents the - asynchronous operation of a Task{Task{TResult}}. - - - It is often useful to be able to return a Task{TResult} from a Task{TResult}, where the inner Task{TResult} - represents work done as part of the outer Task{TResult}. However, doing so results in a Task{Task{TResult}}, - which, if not dealt with carefully, could produce unexpected behavior. Unwrap solves this problem by - creating a proxy Task{TResult} that represents the entire asynchronous operation of such a Task{Task{TResult}}. - - The Task{Task{TResult}} to unwrap. - The exception that is thrown if the - argument is null. - A Task{TResult} that represents the asynchronous operation of the provided Task{Task{TResult}}. /// Unwraps a Task that returns another Task. - - - diff --git a/packages/TaskParallelLibrary.1.0.2856.0/lib/Net35/redist.txt b/packages/TaskParallelLibrary.1.0.2856.0/lib/Net35/redist.txt deleted file mode 100644 index c7972d8..0000000 --- a/packages/TaskParallelLibrary.1.0.2856.0/lib/Net35/redist.txt +++ /dev/null @@ -1,11 +0,0 @@ -The files below can be distributed as described in the MICROSOFT REACTIVE EXTENSTIONS FOR JAVASCRIPT AND .NET LIBRARIES License. - -System.Observable.dll -System.CoreEx.dll -System.Reactive.dll -System.Interactive.dll -System.Threading.dll -System.Linq.Async.dll -System.Reactive.Testing.dll -System.Reactive.ClientProfile.dll -System.Reactive.ExtendedProfile.dll diff --git a/packages/WebSocket4Net.0.14.1/lib/Xamarin.iOS10/WebSocket4Net.dll b/packages/WebSocket4Net.0.14.1/lib/Xamarin.iOS10/WebSocket4Net.dll deleted file mode 100644 index b4a7cc6..0000000 Binary files a/packages/WebSocket4Net.0.14.1/lib/Xamarin.iOS10/WebSocket4Net.dll and /dev/null differ diff --git a/packages/WebSocket4Net.0.14.1/lib/monoandroid23/WebSocket4Net.dll b/packages/WebSocket4Net.0.14.1/lib/monoandroid23/WebSocket4Net.dll deleted file mode 100644 index 7fe6b9b..0000000 Binary files a/packages/WebSocket4Net.0.14.1/lib/monoandroid23/WebSocket4Net.dll and /dev/null differ diff --git a/packages/WebSocket4Net.0.14.1/lib/monotouch10/WebSocket4Net.dll b/packages/WebSocket4Net.0.14.1/lib/monotouch10/WebSocket4Net.dll deleted file mode 100644 index 87b9765..0000000 Binary files a/packages/WebSocket4Net.0.14.1/lib/monotouch10/WebSocket4Net.dll and /dev/null differ diff --git a/packages/WebSocket4Net.0.14.1/lib/net20/WebSocket4Net.dll b/packages/WebSocket4Net.0.14.1/lib/net20/WebSocket4Net.dll deleted file mode 100644 index ffa97af..0000000 Binary files a/packages/WebSocket4Net.0.14.1/lib/net20/WebSocket4Net.dll and /dev/null differ diff --git a/packages/WebSocket4Net.0.14.1/lib/net35/WebSocket4Net.dll b/packages/WebSocket4Net.0.14.1/lib/net35/WebSocket4Net.dll deleted file mode 100644 index 1acc90e..0000000 Binary files a/packages/WebSocket4Net.0.14.1/lib/net35/WebSocket4Net.dll and /dev/null differ diff --git a/packages/WebSocket4Net.0.14.1/lib/net40/WebSocket4Net.dll b/packages/WebSocket4Net.0.14.1/lib/net40/WebSocket4Net.dll deleted file mode 100644 index b695882..0000000 Binary files a/packages/WebSocket4Net.0.14.1/lib/net40/WebSocket4Net.dll and /dev/null differ diff --git a/packages/WebSocket4Net.0.14.1/lib/net45/WebSocket4Net.dll b/packages/WebSocket4Net.0.14.1/lib/net45/WebSocket4Net.dll deleted file mode 100644 index ac6cbce..0000000 Binary files a/packages/WebSocket4Net.0.14.1/lib/net45/WebSocket4Net.dll and /dev/null differ diff --git a/packages/WebSocket4Net.0.14.1/lib/sl40/WebSocket4Net.dll b/packages/WebSocket4Net.0.14.1/lib/sl40/WebSocket4Net.dll deleted file mode 100644 index 9bf37bc..0000000 Binary files a/packages/WebSocket4Net.0.14.1/lib/sl40/WebSocket4Net.dll and /dev/null differ diff --git a/packages/WebSocket4Net.0.14.1/lib/sl50-wp/WebSocket4Net.dll b/packages/WebSocket4Net.0.14.1/lib/sl50-wp/WebSocket4Net.dll deleted file mode 100644 index 4039cf3..0000000 Binary files a/packages/WebSocket4Net.0.14.1/lib/sl50-wp/WebSocket4Net.dll and /dev/null differ diff --git a/packages/WebSocket4Net.0.14.1/lib/sl50/WebSocket4Net.dll b/packages/WebSocket4Net.0.14.1/lib/sl50/WebSocket4Net.dll deleted file mode 100644 index 06f0e0e..0000000 Binary files a/packages/WebSocket4Net.0.14.1/lib/sl50/WebSocket4Net.dll and /dev/null differ diff --git a/packages/WebSocketSharp.1.0.3-rc9/lib/websocket-sharp.dll b/packages/WebSocketSharp.1.0.3-rc9/lib/websocket-sharp.dll deleted file mode 100644 index 79fa7de..0000000 Binary files a/packages/WebSocketSharp.1.0.3-rc9/lib/websocket-sharp.dll and /dev/null differ diff --git a/packages/WebSocketSharp.1.0.3-rc9/lib/websocket-sharp.xml b/packages/WebSocketSharp.1.0.3-rc9/lib/websocket-sharp.xml deleted file mode 100644 index 21fc0cd..0000000 --- a/packages/WebSocketSharp.1.0.3-rc9/lib/websocket-sharp.xml +++ /dev/null @@ -1,7640 +0,0 @@ - - - - websocket-sharp - - - - - Provides a set of static methods for websocket-sharp. - - - - - Determines whether the specified equals the specified , - and invokes the specified Action<int> delegate at the same time. - - - true if equals ; - otherwise, false. - - - An to compare. - - - A to compare. - - - An Action<int> delegate that references the method(s) called - at the same time as comparing. An parameter to pass to - the method(s) is . - - - - - Gets the absolute path from the specified . - - - A that represents the absolute path if it's successfully found; - otherwise, . - - - A that represents the URI to get the absolute path from. - - - - - Gets the name from the specified that contains a pair of name and - value separated by a separator character. - - - A that represents the name if any; otherwise, null. - - - A that contains a pair of name and value separated by - a separator character. - - - A that represents the separator character. - - - - - Gets the value from the specified that contains a pair of name and - value separated by a separator character. - - - A that represents the value if any; otherwise, null. - - - A that contains a pair of name and value separated by - a separator character. - - - A that represents the separator character. - - - - - Tries to create a for WebSocket with - the specified . - - - true if a is successfully created; otherwise, false. - - - A that represents a WebSocket URL to try. - - - When this method returns, a that represents a WebSocket URL, - or if is invalid. - - - When this method returns, a that represents an error message, - or if is valid. - - - - - Determines whether the specified contains any of characters in - the specified array of . - - - true if contains any of ; - otherwise, false. - - - A to test. - - - An array of that contains characters to find. - - - - - Determines whether the specified contains - the entry with the specified . - - - true if contains the entry with - ; otherwise, false. - - - A to test. - - - A that represents the key of the entry to find. - - - - - Determines whether the specified contains the entry with - the specified both and . - - - true if contains the entry with both - and ; otherwise, false. - - - A to test. - - - A that represents the key of the entry to find. - - - A that represents the value of the entry to find. - - - - - Emits the specified delegate if it isn't . - - - A to emit. - - - An from which emits this . - - - A that contains no event data. - - - - - Emits the specified EventHandler<TEventArgs> delegate if it isn't - . - - - An EventHandler<TEventArgs> to emit. - - - An from which emits this . - - - A TEventArgs that represents the event data. - - - The type of the event data generated by the event. - - - - - Gets the collection of the HTTP cookies from the specified HTTP . - - - A that receives a collection of the HTTP cookies. - - - A that contains a collection of the HTTP headers. - - - true if is a collection of the response headers; - otherwise, false. - - - - - Gets the description of the specified HTTP status . - - - A that represents the description of the HTTP status code. - - - One of enum values, indicates the HTTP status code. - - - - - Gets the description of the specified HTTP status . - - - A that represents the description of the HTTP status code. - - - An that represents the HTTP status code. - - - - - Determines whether the specified is in the allowable range of - the WebSocket close status code. - - - Not allowable ranges are the following: - - - - Numbers in the range 0-999 are not used. - - - - - Numbers greater than 4999 are out of the reserved close status code ranges. - - - - - - true if is in the allowable range of the WebSocket - close status code; otherwise, false. - - - A to test. - - - - - Determines whether the specified is enclosed in the specified - . - - - true if is enclosed in ; - otherwise, false. - - - A to test. - - - A that represents the character to find. - - - - - Determines whether the specified is host (this computer - architecture) byte order. - - - true if is host byte order; otherwise, false. - - - One of the enum values, to test. - - - - - Determines whether the specified represents - the local IP address. - - - true if represents the local IP address; - otherwise, false. - - - A to test. - - - - - Determines whether the specified is or empty. - - - true if is or empty; - otherwise, false. - - - A to test. - - - - - Determines whether the specified is a predefined scheme. - - - true if is a predefined scheme; otherwise, false. - - - A to test. - - - - - Determines whether the specified is - an HTTP Upgrade request to switch to the specified . - - - true if is an HTTP Upgrade request to switch to - ; otherwise, false. - - - A that represents the HTTP request. - - - A that represents the protocol name. - - - - is . - - - -or- - - - is . - - - - is empty. - - - - - Determines whether the specified is a URI string. - - - true if may be a URI string; otherwise, false. - - - A to test. - - - - - Retrieves a sub-array from the specified . A sub-array starts at - the specified element position in . - - - An array of T that receives a sub-array, or an empty array of T if any problems with - the parameters. - - - An array of T from which to retrieve a sub-array. - - - An that represents the zero-based starting position of - a sub-array in . - - - An that represents the number of elements to retrieve. - - - The type of elements in . - - - - - Retrieves a sub-array from the specified . A sub-array starts at - the specified element position in . - - - An array of T that receives a sub-array, or an empty array of T if any problems with - the parameters. - - - An array of T from which to retrieve a sub-array. - - - A that represents the zero-based starting position of - a sub-array in . - - - A that represents the number of elements to retrieve. - - - The type of elements in . - - - - - Executes the specified delegate times. - - - An is the number of times to execute. - - - An delegate that references the method(s) to execute. - - - - - Executes the specified delegate times. - - - A is the number of times to execute. - - - An delegate that references the method(s) to execute. - - - - - Executes the specified delegate times. - - - A is the number of times to execute. - - - An delegate that references the method(s) to execute. - - - - - Executes the specified delegate times. - - - A is the number of times to execute. - - - An delegate that references the method(s) to execute. - - - - - Executes the specified Action<int> delegate times. - - - An is the number of times to execute. - - - An Action<int> delegate that references the method(s) to execute. - An parameter to pass to the method(s) is the zero-based count of - iteration. - - - - - Executes the specified Action<long> delegate times. - - - A is the number of times to execute. - - - An Action<long> delegate that references the method(s) to execute. - A parameter to pass to the method(s) is the zero-based count of - iteration. - - - - - Executes the specified Action<uint> delegate times. - - - A is the number of times to execute. - - - An Action<uint> delegate that references the method(s) to execute. - A parameter to pass to the method(s) is the zero-based count of - iteration. - - - - - Executes the specified Action<ulong> delegate times. - - - A is the number of times to execute. - - - An Action<ulong> delegate that references the method(s) to execute. - A parameter to pass to this method(s) is the zero-based count of - iteration. - - - - - Converts the specified array of to the specified type data. - - - A T converted from , or a default value of - T if is an empty array of or - if the type of T isn't , , , - , , , , - , , or . - - - An array of to convert. - - - One of the enum values, indicates the byte order of - . - - - The type of the return. The T must be a value type. - - - is . - - - - - Converts the specified to an array of . - - - An array of converted from . - - - A T to convert. - - - One of the enum values, indicates the byte order of the return. - - - The type of . The T must be a value type. - - - - - Converts the order of the specified array of to the host byte order. - - - An array of converted from . - - - An array of to convert. - - - One of the enum values, indicates the byte order of - . - - - is . - - - - - Converts the specified to a that - concatenates the each element of across the specified - . - - - A converted from , - or if is empty. - - - An array of T to convert. - - - A that represents the separator string. - - - The type of elements in . - - - is . - - - - - Converts the specified to a . - - - A converted from , - or if isn't successfully converted. - - - A to convert. - - - - - URL-decodes the specified . - - - A that receives the decoded string, - or the if it's or empty. - - - A to decode. - - - - - URL-encodes the specified . - - - A that receives the encoded string, - or if it's or empty. - - - A to encode. - - - - - Writes and sends the specified data with the specified - . - - - A that represents the HTTP response used to - send the content data. - - - An array of that represents the content data to send. - - - - is . - - - -or- - - - is . - - - - - - Contains the event data associated with a event. - - - - A event occurs when the receives - a text or binary message, or a Ping if the property is - set to true. - - - If you would like to get the message data, you should access the or - property. - - - - - - Gets the message data as a . - - - A that represents the message data, - or if the message data cannot be decoded to a string. - - - - - Gets the message data as an array of . - - - An array of that represents the message data. - - - - - Gets the type of the message. - - - , , or . - - - - - Contains the event data associated with a event. - - - - A event occurs when the WebSocket connection has been - closed. - - - If you would like to get the reason for the close, you should access - the or property. - - - - - - Gets the status code for the close. - - - A that represents the status code for the close if any. - - - - - Gets the reason for the close. - - - A that represents the reason for the close if any. - - - - - Gets a value indicating whether the WebSocket connection has been closed cleanly. - - - true if the WebSocket connection has been closed cleanly; otherwise, false. - - - - - Contains the values that indicate whether the byte order is a Little-endian or Big-endian. - - - - - Indicates a Little-endian. - - - - - Indicates a Big-endian. - - - - - Contains the event data associated with a event. - - - - A event occurs when the gets - an error. - - - If you would like to get the error message, you should access - the property. - - - And if the error is due to an exception, you can get the - instance by accessing the property. - - - - - - Gets the instance that caused the error. - - - An instance that represents the cause of the error, - or if the error isn't due to an exception. - - - - - Gets the error message. - - - A that represents the error message. - - - - - Implements the WebSocket interface. - - - The WebSocket class provides a set of methods and properties for two-way communication using - the WebSocket protocol (RFC 6455). - - - - - Initializes a new instance of the class with - the specified WebSocket URL and subprotocols. - - - A that represents the WebSocket URL to connect. - - - An array of that contains the WebSocket subprotocols if any. - Each value of must be a token defined in - RFC 2616. - - - is . - - - - is invalid. - - - -or- - - - is invalid. - - - - - - Closes the WebSocket connection, and releases all associated resources. - - - - - Closes the WebSocket connection with the specified , - and releases all associated resources. - - - This method emits a event if isn't in - the allowable range of the close status code. - - - A that represents the status code indicating the reason for the close. - - - - - Closes the WebSocket connection with the specified , - and releases all associated resources. - - - One of the enum values, represents the status code indicating - the reason for the close. - - - - - Closes the WebSocket connection with the specified and - , and releases all associated resources. - - - This method emits a event if isn't in - the allowable range of the close status code or the size of is - greater than 123 bytes. - - - A that represents the status code indicating the reason for the close. - - - A that represents the reason for the close. - - - - - Closes the WebSocket connection with the specified and - , and releases all associated resources. - - - This method emits a event if the size of is - greater than 123 bytes. - - - One of the enum values, represents the status code indicating - the reason for the close. - - - A that represents the reason for the close. - - - - - Closes the WebSocket connection asynchronously, and releases all associated resources. - - - This method doesn't wait for the close to be complete. - - - - - Closes the WebSocket connection asynchronously with the specified , - and releases all associated resources. - - - - This method doesn't wait for the close to be complete. - - - This method emits a event if isn't in - the allowable range of the close status code. - - - - A that represents the status code indicating the reason for the close. - - - - - Closes the WebSocket connection asynchronously with the specified - , and releases all associated resources. - - - This method doesn't wait for the close to be complete. - - - One of the enum values, represents the status code indicating - the reason for the close. - - - - - Closes the WebSocket connection asynchronously with the specified and - , and releases all associated resources. - - - - This method doesn't wait for the close to be complete. - - - This method emits a event if isn't in - the allowable range of the close status code or the size of is - greater than 123 bytes. - - - - A that represents the status code indicating the reason for the close. - - - A that represents the reason for the close. - - - - - Closes the WebSocket connection asynchronously with the specified - and , and releases - all associated resources. - - - - This method doesn't wait for the close to be complete. - - - This method emits a event if the size of - is greater than 123 bytes. - - - - One of the enum values, represents the status code indicating - the reason for the close. - - - A that represents the reason for the close. - - - - - Establishes a WebSocket connection. - - - - - Establishes a WebSocket connection asynchronously. - - - This method doesn't wait for the connect to be complete. - - - - - Sends a Ping using the WebSocket connection. - - - true if the receives a Pong to this Ping in a time; - otherwise, false. - - - - - Sends a Ping with the specified using the WebSocket connection. - - - true if the receives a Pong to this Ping in a time; - otherwise, false. - - - A that represents the message to send. - - - - - Sends binary using the WebSocket connection. - - - An array of that represents the binary data to send. - - - - - Sends the specified as binary data using the WebSocket connection. - - - A that represents the file to send. - - - - - Sends text using the WebSocket connection. - - - A that represents the text data to send. - - - - - Sends binary asynchronously using the WebSocket connection. - - - This method doesn't wait for the send to be complete. - - - An array of that represents the binary data to send. - - - An Action<bool> delegate that references the method(s) called when - the send is complete. A passed to this delegate is true - if the send is complete successfully. - - - - - Sends the specified as binary data asynchronously using - the WebSocket connection. - - - This method doesn't wait for the send to be complete. - - - A that represents the file to send. - - - An Action<bool> delegate that references the method(s) called when - the send is complete. A passed to this delegate is true - if the send is complete successfully. - - - - - Sends text asynchronously using the WebSocket connection. - - - This method doesn't wait for the send to be complete. - - - A that represents the text data to send. - - - An Action<bool> delegate that references the method(s) called when - the send is complete. A passed to this delegate is true - if the send is complete successfully. - - - - - Sends binary data from the specified asynchronously using - the WebSocket connection. - - - This method doesn't wait for the send to be complete. - - - A from which contains the binary data to send. - - - An that represents the number of bytes to send. - - - An Action<bool> delegate that references the method(s) called when - the send is complete. A passed to this delegate is true - if the send is complete successfully. - - - - - Sets an HTTP to send with - the WebSocket connection request to the server. - - - A that represents the cookie to send. - - - - - Sets a pair of and for - the HTTP authentication (Basic/Digest). - - - A that represents the user name used to authenticate. - - - A that represents the password for used - to authenticate. - - - true if the sends the Basic authentication credentials with - the first connection request to the server; otherwise, false. - - - - - Sets an HTTP Proxy server URL to connect through, and if necessary, - a pair of and for - the proxy server authentication (Basic/Digest). - - - A that represents the proxy server URL to connect through. - - - A that represents the user name used to authenticate. - - - A that represents the password for used - to authenticate. - - - - - Closes the WebSocket connection, and releases all associated resources. - - - This method closes the connection with . - - - - - Gets or sets the compression method used to compress the message on - the WebSocket connection. - - - One of the enum values, indicates - the compression method used to compress the message. The default value is - . - - - - - Gets the HTTP cookies included in the WebSocket connection request and response. - - - An - instance that provides an enumerator which supports the iteration over the collection of - the cookies. - - - - - Gets the credentials for the HTTP authentication (Basic/Digest). - - - A that represents the credentials for - the authentication. The default value is . - - - - - Gets or sets a value indicating whether the emits - a event when receives a Ping. - - - true if the emits a event - when receives a Ping; otherwise, false. The default value is false. - - - - - Gets or sets a value indicating whether the redirects to - the new URL located in the handshake response. - - - true if the redirects to the new URL; - otherwise, false. The default value is false. - - - - - Gets the WebSocket extensions selected by the server. - - - A that represents the extensions if any. - The default value is . - - - - - Gets a value indicating whether the WebSocket connection is alive. - - - true if the connection is alive; otherwise, false. - - - - - Gets a value indicating whether the WebSocket connection is secure. - - - true if the connection is secure; otherwise, false. - - - - - Gets the logging functions. - - - The default logging level is . If you would like to change it, - you should set the Log.Level property to any of the enum - values. - - - A that provides the logging functions. - - - - - Gets or sets the value of the HTTP Origin header to send with - the WebSocket connection request to the server. - - - The sends the Origin header if this property has any. - - - - A that represents the value of - the Origin header to send. - The default value is . - - - The Origin header has the following syntax: - <scheme>://<host>[:<port>] - - - - - - Gets the WebSocket subprotocol selected by the server. - - - A that represents the subprotocol if any. - The default value is . - - - - - Gets the state of the WebSocket connection. - - - One of the enum values, indicates the state of - the WebSocket connection. The default value is . - - - - - Gets or sets the SSL configuration used to authenticate the server and - optionally the client for secure connection. - - - A that represents the configuration used - to authenticate the server and optionally the client for secure connection, - or if the is used as server. - - - - - Gets the WebSocket URL to connect. - - - A that represents the WebSocket URL to connect. - - - - - Gets or sets the wait time for the response to the Ping or Close. - - - A that represents the wait time. The default value is - the same as 5 seconds, or 1 second if the is used by - a server. - - - - - Occurs when the WebSocket connection has been closed. - - - - - Occurs when the gets an error. - - - - - Occurs when the receives a message. - - - - - Occurs when the WebSocket connection has been established. - - - - - Provides a WebSocket protocol server. - - - The WebSocketServer class can provide multiple WebSocket services. - - - - - Initializes a new instance of the class. - - - An instance initialized by this constructor listens for the incoming connection requests on - port 80. - - - - - Initializes a new instance of the class with - the specified . - - - - An instance initialized by this constructor listens for the incoming connection requests - on . - - - If is 443, that instance provides a secure connection. - - - - An that represents the port number on which to listen. - - - isn't between 1 and 65535 inclusive. - - - - - Initializes a new instance of the class with - the specified WebSocket URL. - - - - An instance initialized by this constructor listens for the incoming connection requests - on the host name and port in . - - - If doesn't include a port, either port 80 or 443 is used on - which to listen. It's determined by the scheme (ws or wss) in . - (Port 80 if the scheme is ws.) - - - - A that represents the WebSocket URL of the server. - - - is . - - - - is empty. - - - -or- - - - is invalid. - - - - - - Initializes a new instance of the class with - the specified and . - - - An instance initialized by this constructor listens for the incoming connection requests on - . - - - An that represents the port number on which to listen. - - - A that indicates providing a secure connection or not. - (true indicates providing a secure connection.) - - - isn't between 1 and 65535 inclusive. - - - - - Initializes a new instance of the class with - the specified and . - - - - An instance initialized by this constructor listens for the incoming connection requests - on and . - - - If is 443, that instance provides a secure connection. - - - - A that represents the local IP address of the server. - - - An that represents the port number on which to listen. - - - is . - - - isn't a local IP address. - - - isn't between 1 and 65535 inclusive. - - - - - Initializes a new instance of the class with - the specified , , - and . - - - An instance initialized by this constructor listens for the incoming connection requests on - and . - - - A that represents the local IP address of the server. - - - An that represents the port number on which to listen. - - - A that indicates providing a secure connection or not. - (true indicates providing a secure connection.) - - - is . - - - isn't a local IP address. - - - isn't between 1 and 65535 inclusive. - - - - - Adds a WebSocket service with the specified behavior, , - and . - - - - This method converts to URL-decoded string, - and removes '/' from tail end of . - - - returns an initialized specified typed - instance. - - - - A that represents the absolute path to the service to add. - - - A Func<T> delegate that references the method used to initialize - a new specified typed instance (a new - instance). - - - The type of the behavior of the service to add. The TBehavior must inherit - the class. - - - - - Adds a WebSocket service with the specified behavior and . - - - This method converts to URL-decoded string, - and removes '/' from tail end of . - - - A that represents the absolute path to the service to add. - - - The type of the behavior of the service to add. The TBehaviorWithNew must inherit - the class, and must have a public parameterless - constructor. - - - - - Removes the WebSocket service with the specified . - - - This method converts to URL-decoded string, - and removes '/' from tail end of . - - - true if the service is successfully found and removed; otherwise, false. - - - A that represents the absolute path to the service to find. - - - - - Starts receiving the WebSocket connection requests. - - - - - Stops receiving the WebSocket connection requests. - - - - - Stops receiving the WebSocket connection requests with - the specified and . - - - A that represents the status code indicating the reason for the stop. - - - A that represents the reason for the stop. - - - - - Stops receiving the WebSocket connection requests with - the specified and . - - - One of the enum values, represents the status code indicating - the reason for the stop. - - - A that represents the reason for the stop. - - - - - Gets the local IP address of the server. - - - A that represents the local IP address of the server. - - - - - Gets or sets the scheme used to authenticate the clients. - - - One of the enum values, - indicates the scheme used to authenticate the clients. The default value is - . - - - - - Gets a value indicating whether the server has started. - - - true if the server has started; otherwise, false. - - - - - Gets a value indicating whether the server provides a secure connection. - - - true if the server provides a secure connection; otherwise, false. - - - - - Gets or sets a value indicating whether the server cleans up - the inactive sessions periodically. - - - true if the server cleans up the inactive sessions every 60 seconds; - otherwise, false. The default value is true. - - - - - Gets the logging functions. - - - The default logging level is . If you would like to change it, - you should set the Log.Level property to any of the enum - values. - - - A that provides the logging functions. - - - - - Gets the port on which to listen for incoming connection requests. - - - An that represents the port number on which to listen. - - - - - Gets or sets the name of the realm associated with the server. - - - A that represents the name of the realm. The default value is - "SECRET AREA". - - - - - Gets or sets a value indicating whether the server is allowed to be bound to - an address that is already in use. - - - If you would like to resolve to wait for socket in TIME_WAIT state, - you should set this property to true. - - - true if the server is allowed to be bound to an address that is already in use; - otherwise, false. The default value is false. - - - - - Gets or sets the SSL configuration used to authenticate the server and - optionally the client for secure connection. - - - A that represents the configuration used to - authenticate the server and optionally the client for secure connection. - - - - - Gets or sets the delegate called to find the credentials for an identity used to - authenticate a client. - - - A Func<, > delegate that - references the method(s) used to find the credentials. The default value is a function that - only returns . - - - - - Gets or sets the wait time for the response to the WebSocket Ping or Close. - - - A that represents the wait time. The default value is - the same as 1 second. - - - - - Gets the access to the WebSocket services provided by the server. - - - A that manages the WebSocket services. - - - - - Contains the values of the schemes for authentication. - - - - - Indicates that no authentication is allowed. - - - - - Indicates digest authentication. - - - - - Indicates basic authentication. - - - - - Indicates anonymous authentication. - - - - - Provides a set of methods and properties used to manage an HTTP Cookie. - - - - The Cookie class supports the following cookie formats: - Netscape specification, - RFC 2109, and - RFC 2965 - - - The Cookie class cannot be inherited. - - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with the specified - and . - - - A that represents the Name of the cookie. - - - A that represents the Value of the cookie. - - - - is or empty. - - - - or - - - - contains an invalid character. - - - - or - - - - is . - - - - or - - - - contains a string not enclosed in double quotes - that contains an invalid character. - - - - - - Initializes a new instance of the class with the specified - , , and . - - - A that represents the Name of the cookie. - - - A that represents the Value of the cookie. - - - A that represents the value of the Path attribute of the cookie. - - - - is or empty. - - - - or - - - - contains an invalid character. - - - - or - - - - is . - - - - or - - - - contains a string not enclosed in double quotes - that contains an invalid character. - - - - - - Initializes a new instance of the class with the specified - , , , and - . - - - A that represents the Name of the cookie. - - - A that represents the Value of the cookie. - - - A that represents the value of the Path attribute of the cookie. - - - A that represents the value of the Domain attribute of the cookie. - - - - is or empty. - - - - or - - - - contains an invalid character. - - - - or - - - - is . - - - - or - - - - contains a string not enclosed in double quotes - that contains an invalid character. - - - - - - Determines whether the specified is equal to the current - . - - - An to compare with the current . - - - true if is equal to the current ; - otherwise, false. - - - - - Serves as a hash function for a object. - - - An that represents the hash code for the current . - - - - - Returns a that represents the current . - - - This method returns a to use to send an HTTP Cookie to - an origin server. - - - A that represents the current . - - - - - Gets or sets the value of the Comment attribute of the cookie. - - - A that represents the comment to document intended use of the cookie. - - - - - Gets or sets the value of the CommentURL attribute of the cookie. - - - A that represents the URI that provides the comment to document intended - use of the cookie. - - - - - Gets or sets a value indicating whether the client discards the cookie unconditionally - when the client terminates. - - - true if the client discards the cookie unconditionally when the client terminates; - otherwise, false. The default value is false. - - - - - Gets or sets the value of the Domain attribute of the cookie. - - - A that represents the URI for which the cookie is valid. - - - - - Gets or sets a value indicating whether the cookie has expired. - - - true if the cookie has expired; otherwise, false. - The default value is false. - - - - - Gets or sets the value of the Expires attribute of the cookie. - - - A that represents the date and time at which the cookie expires. - The default value is . - - - - - Gets or sets a value indicating whether non-HTTP APIs can access the cookie. - - - true if non-HTTP APIs cannot access the cookie; otherwise, false. - The default value is false. - - - - - Gets or sets the Name of the cookie. - - - A that represents the Name of the cookie. - - - - The value specified for a set operation is or empty. - - - - or - - - - The value specified for a set operation contains an invalid character. - - - - - - Gets or sets the value of the Path attribute of the cookie. - - - A that represents the subset of URI on the origin server - to which the cookie applies. - - - - - Gets or sets the value of the Port attribute of the cookie. - - - A that represents the list of TCP ports to which the cookie applies. - - - The value specified for a set operation isn't enclosed in double quotes or - couldn't be parsed. - - - - - Gets or sets a value indicating whether the security level of the cookie is secure. - - - When this property is true, the cookie may be included in the HTTP request - only if the request is transmitted over the HTTPS. - - - true if the security level of the cookie is secure; otherwise, false. - The default value is false. - - - - - Gets the time when the cookie was issued. - - - A that represents the time when the cookie was issued. - - - - - Gets or sets the Value of the cookie. - - - A that represents the Value of the cookie. - - - - The value specified for a set operation is . - - - - or - - - - The value specified for a set operation contains a string not enclosed in double quotes - that contains an invalid character. - - - - - - Gets or sets the value of the Version attribute of the cookie. - - - An that represents the version of the HTTP state management - to which the cookie conforms. - - - The value specified for a set operation isn't 0 or 1. - - - - - Provides a collection container for instances of the class. - - - - - Initializes a new instance of the class. - - - - - Adds the specified to the collection. - - - A to add. - - - is . - - - - - Adds the specified to the collection. - - - A that contains the cookies to add. - - - is . - - - - - Copies the elements of the collection to the specified , starting at - the specified in the . - - - An that represents the destination of the elements copied from - the collection. - - - An that represents the zero-based index in - at which copying begins. - - - is . - - - is less than zero. - - - - is multidimensional. - - - -or- - - - The number of elements in the collection is greater than the available space from - to the end of the destination . - - - - The elements in the collection cannot be cast automatically to the type of the destination - . - - - - - Copies the elements of the collection to the specified array of , - starting at the specified in the . - - - An array of that represents the destination of the elements - copied from the collection. - - - An that represents the zero-based index in - at which copying begins. - - - is . - - - is less than zero. - - - The number of elements in the collection is greater than the available space from - to the end of the destination . - - - - - Gets the enumerator used to iterate through the collection. - - - An instance used to iterate through the collection. - - - - - Gets the number of cookies in the collection. - - - An that represents the number of cookies in the collection. - - - - - Gets a value indicating whether the collection is read-only. - - - true if the collection is read-only; otherwise, false. - The default value is true. - - - - - Gets a value indicating whether the access to the collection is thread safe. - - - true if the access to the collection is thread safe; otherwise, false. - The default value is false. - - - - - Gets the at the specified from - the collection. - - - A at the specified in the collection. - - - An that represents the zero-based index of the - to find. - - - is out of allowable range of indexes for the collection. - - - - - Gets the with the specified from - the collection. - - - A with the specified in the collection. - - - A that represents the name of the to find. - - - is . - - - - - Gets an object used to synchronize access to the collection. - - - An used to synchronize access to the collection. - - - - - The exception that is thrown when a gets an error. - - - - - Initializes a new instance of the class from - the specified and . - - - A that contains the serialized object data. - - - A that specifies the source for the deserialization. - - - - - Initializes a new instance of the class. - - - - - Populates the specified with the data needed to serialize - the current . - - - A that holds the serialized object data. - - - A that specifies the destination for the serialization. - - - - - Populates the specified with the data needed to serialize - the current . - - - A that holds the serialized object data. - - - A that specifies the destination for the serialization. - - - - - Provides a simple, programmatically controlled HTTP listener. - - - - - Initializes a new instance of the class. - - - - - Shuts down the listener immediately. - - - - - Begins getting an incoming request asynchronously. - - - This asynchronous operation must be completed by calling the EndGetContext method. - Typically, the method is invoked by the delegate. - - - An that represents the status of the asynchronous operation. - - - An delegate that references the method to invoke when - the asynchronous operation completes. - - - An that represents a user defined object to pass to - the delegate. - - - - This listener has no URI prefix on which listens. - - - -or- - - - This listener hasn't been started, or is currently stopped. - - - - This listener has been closed. - - - - - Shuts down the listener. - - - - - Ends an asynchronous operation to get an incoming request. - - - This method completes an asynchronous operation started by calling - the BeginGetContext method. - - - A that represents a request. - - - An obtained by calling the BeginGetContext method. - - - is . - - - wasn't obtained by calling the BeginGetContext method. - - - This method was already called for the specified . - - - This listener has been closed. - - - - - Gets an incoming request. - - - This method waits for an incoming request, and returns when a request is received. - - - A that represents a request. - - - - This listener has no URI prefix on which listens. - - - -or- - - - This listener hasn't been started, or is currently stopped. - - - - This listener has been closed. - - - - - Starts receiving incoming requests. - - - This listener has been closed. - - - - - Stops receiving incoming requests. - - - This listener has been closed. - - - - - Releases all resources used by the listener. - - - - - Gets or sets the scheme used to authenticate the clients. - - - One of the enum values, - represents the scheme used to authenticate the clients. The default value is - . - - - This listener has been closed. - - - - - Gets or sets the delegate called to select the scheme used to authenticate the clients. - - - If you set this property, the listener uses the authentication scheme selected by - the delegate for each request. Or if you don't set, the listener uses the value of - the property as the authentication - scheme for all requests. - - - A Func<, > - delegate that references the method used to select an authentication scheme. The default - value is . - - - This listener has been closed. - - - - - Gets or sets the path to the folder in which stores the certificate files used to - authenticate the server on the secure connection. - - - - This property represents the path to the folder in which stores the certificate files - associated with each port number of added URI prefixes. A set of the certificate files - is a pair of the 'port number'.cer (DER) and 'port number'.key - (DER, RSA Private Key). - - - If this property is or empty, the result of - System.Environment.GetFolderPath - () is used as the default path. - - - - A that represents the path to the folder in which stores - the certificate files. The default value is . - - - This listener has been closed. - - - - - Gets or sets a value indicating whether the listener returns exceptions that occur when - sending the response to the client. - - - true if the listener shouldn't return those exceptions; otherwise, false. - The default value is false. - - - This listener has been closed. - - - - - Gets a value indicating whether the listener has been started. - - - true if the listener has been started; otherwise, false. - - - - - Gets a value indicating whether the listener can be used with the current operating system. - - - true. - - - - - Gets the logging functions. - - - The default logging level is . If you would like to change it, - you should set the Log.Level property to any of the enum - values. - - - A that provides the logging functions. - - - - - Gets the URI prefixes handled by the listener. - - - A that contains the URI prefixes. - - - This listener has been closed. - - - - - Gets or sets the name of the realm associated with the listener. - - - A that represents the name of the realm. The default value is - "SECRET AREA". - - - This listener has been closed. - - - - - Gets or sets the SSL configuration used to authenticate the server and - optionally the client for secure connection. - - - A that represents the configuration used to - authenticate the server and optionally the client for secure connection. - - - This listener has been closed. - - - - - Gets or sets a value indicating whether, when NTLM authentication is used, - the authentication information of first request is used to authenticate - additional requests on the same connection. - - - This property isn't currently supported and always throws - a . - - - true if the authentication information of first request is used; - otherwise, false. - - - Any use of this property. - - - - - Gets or sets the delegate called to find the credentials for an identity used to - authenticate a client. - - - A Func<, > delegate that - references the method used to find the credentials. The default value is a function that - only returns . - - - This listener has been closed. - - - - - Provides the access to the HTTP request and response information - used by the . - - - The HttpListenerContext class cannot be inherited. - - - - - Accepts a WebSocket connection request. - - - A that represents the WebSocket connection - request. - - - A that represents the subprotocol used in the WebSocket connection. - - - - is empty. - - - -or- - - - contains an invalid character. - - - - - - Gets the HTTP request information from a client. - - - A that represents the HTTP request. - - - - - Gets the HTTP response information used to send to the client. - - - A that represents the HTTP response to send. - - - - - Gets the client information (identity, authentication, and security roles). - - - A instance that represents the client information. - - - - - The exception that is thrown when a gets an error - processing an HTTP request. - - - - - Initializes a new instance of the class from - the specified and . - - - A that contains the serialized object data. - - - A that specifies the source for the deserialization. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class - with the specified . - - - An that identifies the error. - - - - - Initializes a new instance of the class - with the specified and . - - - An that identifies the error. - - - A that describes the error. - - - - - Gets the error code that identifies the error that occurred. - - - An that identifies the error. - - - - - Provides the collection used to store the URI prefixes for the . - - - The responds to the request which has a requested URI that - the prefixes most closely match. - - - - - Adds the specified to the collection. - - - A that represents the URI prefix to add. The prefix must be - a well-formed URI prefix with http or https scheme, and must end with a '/'. - - - is . - - - is invalid. - - - The associated with this collection is closed. - - - - - Removes all URI prefixes from the collection. - - - The associated with this collection is closed. - - - - - Returns a value indicating whether the collection contains the specified - . - - - true if the collection contains ; - otherwise, false. - - - A that represents the URI prefix to test. - - - is . - - - The associated with this collection is closed. - - - - - Copies the contents of the collection to the specified . - - - An that receives the URI prefix strings in the collection. - - - An that represents the zero-based index in - at which copying begins. - - - The associated with this collection is closed. - - - - - Copies the contents of the collection to the specified array of . - - - An array of that receives the URI prefix strings in the collection. - - - An that represents the zero-based index in - at which copying begins. - - - The associated with this collection is closed. - - - - - Gets the enumerator used to iterate through the . - - - An instance used to iterate - through the collection. - - - - - Removes the specified from the collection. - - - true if is successfully found and removed; - otherwise, false. - - - A that represents the URI prefix to remove. - - - is . - - - The associated with this collection is closed. - - - - - Gets the enumerator used to iterate through the . - - - An instance used to iterate through the collection. - - - - - Gets the number of prefixes in the collection. - - - An that represents the number of prefixes. - - - - - Gets a value indicating whether the access to the collection is read-only. - - - Always returns false. - - - - - Gets a value indicating whether the access to the collection is synchronized. - - - Always returns false. - - - - - Provides the access to a request to the . - - - The HttpListenerRequest class cannot be inherited. - - - - - Begins getting the client's X.509 v.3 certificate asynchronously. - - - This asynchronous operation must be completed by calling - the method. Typically, - that method is invoked by the delegate. - - - An that contains the status of the asynchronous operation. - - - An delegate that references the method(s) called when - the asynchronous operation completes. - - - An that contains a user defined object to pass to - the delegate. - - - This method isn't implemented. - - - - - Ends an asynchronous operation to get the client's X.509 v.3 certificate. - - - This method completes an asynchronous operation started by calling - the method. - - - A that contains the client's X.509 v.3 certificate. - - - An obtained by calling - the method. - - - This method isn't implemented. - - - - - Gets the client's X.509 v.3 certificate. - - - A that contains the client's X.509 v.3 certificate. - - - This method isn't implemented. - - - - - Returns a that represents - the current . - - - A that represents the current . - - - - - Gets the media types which are acceptable for the response. - - - An array of that contains the media type names in - the Accept request-header, or if the request didn't include - the Accept header. - - - - - Gets an error code that identifies a problem with the client's certificate. - - - Always returns 0. - - - - - Gets the encoding for the entity body data included in the request. - - - A that represents the encoding for the entity body data, - or if the request didn't include the information about - the encoding. - - - - - Gets the number of bytes in the entity body data included in the request. - - - A that represents the value of the Content-Length entity-header, - or -1 if the value isn't known. - - - - - Gets the media type of the entity body included in the request. - - - A that represents the value of the Content-Type entity-header. - - - - - Gets the cookies included in the request. - - - A that contains the cookies included in the request. - - - - - Gets a value indicating whether the request has the entity body. - - - true if the request has the entity body; otherwise, false. - - - - - Gets the HTTP headers used in the request. - - - A that contains the HTTP headers used in the request. - - - - - Gets the HTTP method used in the request. - - - A that represents the HTTP method used in the request. - - - - - Gets a that contains the entity body data included in the request. - - - A that contains the entity body data included in the request. - - - - - Gets a value indicating whether the client that sent the request is authenticated. - - - true if the client is authenticated; otherwise, false. - - - - - Gets a value indicating whether the request is sent from the local computer. - - - true if the request is sent from the local computer; otherwise, false. - - - - - Gets a value indicating whether the HTTP connection is secured using the SSL protocol. - - - true if the HTTP connection is secured; otherwise, false. - - - - - Gets a value indicating whether the request is a WebSocket connection request. - - - true if the request is a WebSocket connection request; otherwise, false. - - - - - Gets a value indicating whether the client requests a persistent connection. - - - true if the client requests a persistent connection; otherwise, false. - - - - - Gets the server endpoint as an IP address and a port number. - - - A that represents the server endpoint. - - - - - Gets the HTTP version used in the request. - - - A that represents the HTTP version used in the request. - - - - - Gets the query string included in the request. - - - A that contains the query string parameters. - - - - - Gets the raw URL (without the scheme, host, and port) requested by the client. - - - A that represents the raw URL requested by the client. - - - - - Gets the client endpoint as an IP address and a port number. - - - A that represents the client endpoint. - - - - - Gets the request identifier of a incoming HTTP request. - - - A that represents the identifier of a request. - - - - - Gets the URL requested by the client. - - - A that represents the URL requested by the client. - - - - - Gets the URL of the resource from which the requested URL was obtained. - - - A that represents the value of the Referer request-header, - or if the request didn't include an Referer header. - - - - - Gets the information about the user agent originating the request. - - - A that represents the value of the User-Agent request-header. - - - - - Gets the server endpoint as an IP address and a port number. - - - A that represents the server endpoint. - - - - - Gets the internet host name and port number (if present) specified by the client. - - - A that represents the value of the Host request-header. - - - - - Gets the natural languages which are preferred for the response. - - - An array of that contains the natural language names in - the Accept-Language request-header, or if the request - didn't include an Accept-Language header. - - - - - Provides the access to a response to a request received by the . - - - The HttpListenerResponse class cannot be inherited. - - - - - Closes the connection to the client without returning a response. - - - - - Adds an HTTP header with the specified and - to the headers for the response. - - - A that represents the name of the header to add. - - - A that represents the value of the header to add. - - - is or empty. - - - - or contains invalid characters. - - - -or- - - - is a restricted header name. - - - - The length of is greater than 65,535 characters. - - - The header cannot be allowed to add to the current headers. - - - - - Appends the specified to the cookies sent with the response. - - - A to append. - - - is . - - - - - Appends a to the specified HTTP header sent with the response. - - - A that represents the name of the header to append - to. - - - A that represents the value to append to the header. - - - is or empty. - - - - or contains invalid characters. - - - -or- - - - is a restricted header name. - - - - The length of is greater than 65,535 characters. - - - The current headers cannot allow the header to append a value. - - - - - Returns the response to the client and releases the resources used by - this instance. - - - - - Returns the response with the specified array of to the client and - releases the resources used by this instance. - - - An array of that contains the response entity body data. - - - true if this method blocks execution while flushing the stream to the client; - otherwise, false. - - - is . - - - This object is closed. - - - - - Copies some properties from the specified to - this response. - - - A to copy. - - - is . - - - - - Configures the response to redirect the client's request to - the specified . - - - This method sets the property to - , the property to - 302, and the property to - "Found". - - - A that represents the URL to redirect the client's request to. - - - is . - - - isn't an absolute URL. - - - The response has already been sent. - - - This object is closed. - - - - - Adds or updates a in the cookies sent with the response. - - - A to set. - - - is . - - - already exists in the cookies and couldn't be replaced. - - - - - Releases all resources used by the . - - - - - Gets or sets the encoding for the entity body data included in the response. - - - A that represents the encoding for the entity body data, - or if no encoding is specified. - - - This object is closed. - - - - - Gets or sets the number of bytes in the entity body data included in the response. - - - A that represents the value of the Content-Length entity-header. - - - The value specified for a set operation is less than zero. - - - The response has already been sent. - - - This object is closed. - - - - - Gets or sets the media type of the entity body included in the response. - - - A that represents the media type of the entity body, - or if no media type is specified. This value is - used for the value of the Content-Type entity-header. - - - The value specified for a set operation is empty. - - - This object is closed. - - - - - Gets or sets the cookies sent with the response. - - - A that contains the cookies sent with the response. - - - - - Gets or sets the HTTP headers sent to the client. - - - A that contains the headers sent to the client. - - - The value specified for a set operation isn't valid for a response. - - - - - Gets or sets a value indicating whether the server requests a persistent connection. - - - true if the server requests a persistent connection; otherwise, false. - The default value is true. - - - The response has already been sent. - - - This object is closed. - - - - - Gets a to use to write the entity body data. - - - A to use to write the entity body data. - - - This object is closed. - - - - - Gets or sets the HTTP version used in the response. - - - A that represents the version used in the response. - - - The value specified for a set operation is . - - - The value specified for a set operation doesn't have its Major property set to 1 or - doesn't have its Minor property set to either 0 or 1. - - - The response has already been sent. - - - This object is closed. - - - - - Gets or sets the URL to which the client is redirected to locate a requested resource. - - - A that represents the value of the Location response-header, - or if no redirect location is specified. - - - The value specified for a set operation isn't an absolute URL. - - - This object is closed. - - - - - Gets or sets a value indicating whether the response uses the chunked transfer encoding. - - - true if the response uses the chunked transfer encoding; - otherwise, false. The default value is false. - - - The response has already been sent. - - - This object is closed. - - - - - Gets or sets the HTTP status code returned to the client. - - - An that represents the status code for the response to - the request. The default value is same as . - - - The response has already been sent. - - - This object is closed. - - - The value specified for a set operation is invalid. Valid values are - between 100 and 999 inclusive. - - - - - Gets or sets the description of the HTTP status code returned to the client. - - - A that represents the description of the status code. The default - value is the RFC 2616 - description for the property value, - or if an RFC 2616 description doesn't exist. - - - The value specified for a set operation contains invalid characters. - - - The response has already been sent. - - - This object is closed. - - - - - Decodes an HTML-encoded and returns the decoded . - - - A that represents the decoded string. - - - A to decode. - - - - - Decodes an HTML-encoded and sends the decoded - to the specified . - - - A to decode. - - - A that receives the decoded string. - - - - - HTML-encodes a and returns the encoded . - - - A that represents the encoded string. - - - A to encode. - - - - - HTML-encodes a and sends the encoded - to the specified . - - - A to encode. - - - A that receives the encoded string. - - - - - Provides a collection of the HTTP headers associated with a request or response. - - - - - Initializes a new instance of the class from - the specified and . - - - A that contains the serialized object data. - - - A that specifies the source for the deserialization. - - - is . - - - An element with the specified name isn't found in . - - - - - Initializes a new instance of the class. - - - - - Adds a header to the collection without checking if the header is on - the restricted header list. - - - A that represents the name of the header to add. - - - A that represents the value of the header to add. - - - is or empty. - - - or contains invalid characters. - - - The length of is greater than 65,535 characters. - - - The current instance doesn't allow - the . - - - - - Adds the specified to the collection. - - - A that represents the header with the name and value separated by - a colon (':'). - - - is , empty, or the name part of - is empty. - - - - doesn't contain a colon. - - - -or- - - - is a restricted header. - - - -or- - - - The name or value part of contains invalid characters. - - - - The length of the value part of is greater than 65,535 characters. - - - The current instance doesn't allow - the . - - - - - Adds the specified request with - the specified to the collection. - - - One of the enum values, represents - the request header to add. - - - A that represents the value of the header to add. - - - - is a restricted header. - - - -or- - - - contains invalid characters. - - - - The length of is greater than 65,535 characters. - - - The current instance doesn't allow - the request . - - - - - Adds the specified response with - the specified to the collection. - - - One of the enum values, represents - the response header to add. - - - A that represents the value of the header to add. - - - - is a restricted header. - - - -or- - - - contains invalid characters. - - - - The length of is greater than 65,535 characters. - - - The current instance doesn't allow - the response . - - - - - Adds a header with the specified and - to the collection. - - - A that represents the name of the header to add. - - - A that represents the value of the header to add. - - - is or empty. - - - - or contains invalid characters. - - - -or- - - - is a restricted header name. - - - - The length of is greater than 65,535 characters. - - - The current instance doesn't allow - the header . - - - - - Removes all headers from the collection. - - - - - Get the value of the header at the specified in the collection. - - - A that receives the value of the header. - - - An that represents the zero-based index of the header to find. - - - is out of allowable range of indexes for the collection. - - - - - Get the value of the header with the specified in the collection. - - - A that receives the value of the header if found; - otherwise, . - - - A that represents the name of the header to find. - - - - - Gets the enumerator used to iterate through the collection. - - - An instance used to iterate through the collection. - - - - - Get the name of the header at the specified in the collection. - - - A that receives the header name. - - - An that represents the zero-based index of the header to find. - - - is out of allowable range of indexes for the collection. - - - - - Gets an array of header values stored in the specified position of - the collection. - - - An array of that receives the header values if found; - otherwise, . - - - An that represents the zero-based index of the header to find. - - - is out of allowable range of indexes for the collection. - - - - - Gets an array of header values stored in the specified . - - - An array of that receives the header values if found; - otherwise, . - - - A that represents the name of the header to find. - - - - - Populates the specified with the data needed to serialize - the . - - - A that holds the serialized object data. - - - A that specifies the destination for the serialization. - - - is . - - - - - Determines whether the specified header can be set for the request. - - - true if the header is restricted; otherwise, false. - - - A that represents the name of the header to test. - - - is or empty. - - - contains invalid characters. - - - - - Determines whether the specified header can be set for the request or the response. - - - true if the header is restricted; otherwise, false. - - - A that represents the name of the header to test. - - - true if does the test for the response; for the request, false. - - - is or empty. - - - contains invalid characters. - - - - - Implements the interface and raises the deserialization event - when the deserialization is complete. - - - An that represents the source of the deserialization event. - - - - - Removes the specified request from the collection. - - - One of the enum values, represents - the request header to remove. - - - is a restricted header. - - - The current instance doesn't allow - the request . - - - - - Removes the specified response from the collection. - - - One of the enum values, represents - the response header to remove. - - - is a restricted header. - - - The current instance doesn't allow - the response . - - - - - Removes the specified header from the collection. - - - A that represents the name of the header to remove. - - - is or empty. - - - - contains invalid characters. - - - -or- - - - is a restricted header name. - - - - The current instance doesn't allow - the header . - - - - - Sets the specified request to the specified value. - - - One of the enum values, represents - the request header to set. - - - A that represents the value of the request header to set. - - - - is a restricted header. - - - -or- - - - contains invalid characters. - - - - The length of is greater than 65,535 characters. - - - The current instance doesn't allow - the request . - - - - - Sets the specified response to the specified value. - - - One of the enum values, represents - the response header to set. - - - A that represents the value of the response header to set. - - - - is a restricted header. - - - -or- - - - contains invalid characters. - - - - The length of is greater than 65,535 characters. - - - The current instance doesn't allow - the response . - - - - - Sets the specified header to the specified value. - - - A that represents the name of the header to set. - - - A that represents the value of the header to set. - - - is or empty. - - - - or contains invalid characters. - - - -or- - - - is a restricted header name. - - - - The length of is greater than 65,535 characters. - - - The current instance doesn't allow - the header . - - - - - Converts the current to an array of . - - - An array of that receives the converted current - . - - - - - Returns a that represents the current - . - - - A that represents the current . - - - - - Populates the specified with the data needed to serialize - the current . - - - A that holds the serialized object data. - - - A that specifies the destination for the serialization. - - - is . - - - - - Gets all header names in the collection. - - - An array of that contains all header names in the collection. - - - - - Gets the number of headers in the collection. - - - An that represents the number of headers in the collection. - - - - - Gets or sets the specified request in the collection. - - - A that represents the value of the request . - - - One of the enum values, represents - the request header to get or set. - - - - is a restricted header. - - - -or- - - - contains invalid characters. - - - - The length of is greater than 65,535 characters. - - - The current instance doesn't allow - the request . - - - - - Gets or sets the specified response in the collection. - - - A that represents the value of the response . - - - One of the enum values, represents - the response header to get or set. - - - - is a restricted header. - - - -or- - - - contains invalid characters. - - - - The length of is greater than 65,535 characters. - - - The current instance doesn't allow - the response . - - - - - Gets a collection of header names in the collection. - - - A that contains - all header names in the collection. - - - - - Provides a simple HTTP server that allows to accept the WebSocket connection requests. - - - The HttpServer class can provide multiple WebSocket services. - - - - - Initializes a new instance of the class. - - - An instance initialized by this constructor listens for the incoming requests on port 80. - - - - - Initializes a new instance of the class with - the specified . - - - - An instance initialized by this constructor listens for the incoming requests on - . - - - If is 443, that instance provides a secure connection. - - - - An that represents the port number on which to listen. - - - isn't between 1 and 65535 inclusive. - - - - - Initializes a new instance of the class with - the specified HTTP URL. - - - - An instance initialized by this constructor listens for the incoming requests on - the host name and port in . - - - If doesn't include a port, either port 80 or 443 is used on - which to listen. It's determined by the scheme (http or https) in . - (Port 80 if the scheme is http.) - - - - A that represents the HTTP URL of the server. - - - is . - - - - is empty. - - - -or- - - - is invalid. - - - - - - Initializes a new instance of the class with - the specified and . - - - An instance initialized by this constructor listens for the incoming requests on - . - - - An that represents the port number on which to listen. - - - A that indicates providing a secure connection or not. - (true indicates providing a secure connection.) - - - isn't between 1 and 65535 inclusive. - - - - - Initializes a new instance of the class with - the specified and . - - - - An instance initialized by this constructor listens for the incoming requests on - and . - - - If is 443, that instance provides a secure connection. - - - - A that represents the local IP address of the server. - - - An that represents the port number on which to listen. - - - is . - - - isn't a local IP address. - - - isn't between 1 and 65535 inclusive. - - - - - Initializes a new instance of the class with - the specified , , - and . - - - An instance initialized by this constructor listens for the incoming requests on - and . - - - A that represents the local IP address of the server. - - - An that represents the port number on which to listen. - - - A that indicates providing a secure connection or not. - (true indicates providing a secure connection.) - - - is . - - - isn't a local IP address. - - - isn't between 1 and 65535 inclusive. - - - - - Adds the WebSocket service with the specified behavior, , - and . - - - - This method converts to URL-decoded string, - and removes '/' from tail end of . - - - returns an initialized specified typed - instance. - - - - A that represents the absolute path to the service to add. - - - A Func<T> delegate that references the method used to initialize - a new specified typed instance (a new - instance). - - - The type of the behavior of the service to add. The TBehavior must inherit - the class. - - - - - Adds a WebSocket service with the specified behavior and . - - - This method converts to URL-decoded string, - and removes '/' from tail end of . - - - A that represents the absolute path to the service to add. - - - The type of the behavior of the service to add. The TBehaviorWithNew must inherit - the class, and must have a public parameterless - constructor. - - - - - Gets the contents of the file with the specified . - - - An array of that receives the contents of the file, - or if it doesn't exist. - - - A that represents the virtual path to the file to find. - - - - - Removes the WebSocket service with the specified . - - - This method converts to URL-decoded string, - and removes '/' from tail end of . - - - true if the service is successfully found and removed; otherwise, false. - - - A that represents the absolute path to the service to find. - - - - - Starts receiving the HTTP requests. - - - - - Stops receiving the HTTP requests. - - - - - Stops receiving the HTTP requests with the specified and - used to stop the WebSocket services. - - - A that represents the status code indicating the reason for the stop. - - - A that represents the reason for the stop. - - - - - Stops receiving the HTTP requests with the specified and - used to stop the WebSocket services. - - - One of the enum values, represents the status code indicating - the reason for the stop. - - - A that represents the reason for the stop. - - - - - Gets the local IP address of the server. - - - A that represents the local IP address of the server. - - - - - Gets or sets the scheme used to authenticate the clients. - - - One of the enum values, - indicates the scheme used to authenticate the clients. The default value is - . - - - - - Gets a value indicating whether the server has started. - - - true if the server has started; otherwise, false. - - - - - Gets a value indicating whether the server provides a secure connection. - - - true if the server provides a secure connection; otherwise, false. - - - - - Gets or sets a value indicating whether the server cleans up - the inactive sessions in the WebSocket services periodically. - - - true if the server cleans up the inactive sessions every 60 seconds; - otherwise, false. The default value is true. - - - - - Gets the logging functions. - - - The default logging level is . If you would like to change it, - you should set the Log.Level property to any of the enum - values. - - - A that provides the logging functions. - - - - - Gets the port on which to listen for incoming requests. - - - An that represents the port number on which to listen. - - - - - Gets or sets the name of the realm associated with the server. - - - A that represents the name of the realm. The default value is - "SECRET AREA". - - - - - Gets or sets a value indicating whether the server is allowed to be bound to - an address that is already in use. - - - If you would like to resolve to wait for socket in TIME_WAIT state, - you should set this property to true. - - - true if the server is allowed to be bound to an address that is already in use; - otherwise, false. The default value is false. - - - - - Gets or sets the document root path of the server. - - - A that represents the document root path of the server. - The default value is "./Public". - - - - - Gets or sets the SSL configuration used to authenticate the server and - optionally the client for secure connection. - - - A that represents the configuration used to - authenticate the server and optionally the client for secure connection. - - - - - Gets or sets the delegate called to find the credentials for an identity used to - authenticate a client. - - - A Func<, > delegate that - references the method(s) used to find the credentials. The default value is a function that - only returns . - - - - - Gets or sets the wait time for the response to the WebSocket Ping or Close. - - - A that represents the wait time. The default value is - the same as 1 second. - - - - - Gets the access to the WebSocket services provided by the server. - - - A that manages the WebSocket services. - - - - - Occurs when the server receives an HTTP CONNECT request. - - - - - Occurs when the server receives an HTTP DELETE request. - - - - - Occurs when the server receives an HTTP GET request. - - - - - Occurs when the server receives an HTTP HEAD request. - - - - - Occurs when the server receives an HTTP OPTIONS request. - - - - - Occurs when the server receives an HTTP PATCH request. - - - - - Occurs when the server receives an HTTP POST request. - - - - - Occurs when the server receives an HTTP PUT request. - - - - - Occurs when the server receives an HTTP TRACE request. - - - - - Provides the HTTP version numbers. - - - - - Provides a instance for the HTTP/1.0. - - - - - Provides a instance for the HTTP/1.1. - - - - - Initializes a new instance of the class. - - - - - Contains the values of the HTTP status codes. - - - The HttpStatusCode enumeration contains the values of the HTTP status codes defined in - RFC 2616 for the HTTP/1.1. - - - - - Equivalent to status code 100. - Indicates that the client should continue with its request. - - - - - Equivalent to status code 101. - Indicates that the server is switching the HTTP version or protocol on the connection. - - - - - Equivalent to status code 200. - Indicates that the client's request has succeeded. - - - - - Equivalent to status code 201. - Indicates that the client's request has been fulfilled and resulted in a new resource being - created. - - - - - Equivalent to status code 202. - Indicates that the client's request has been accepted for processing, but the processing - hasn't been completed. - - - - - Equivalent to status code 203. - Indicates that the returned metainformation is from a local or a third-party copy instead of - the origin server. - - - - - Equivalent to status code 204. - Indicates that the server has fulfilled the client's request but doesn't need to return - an entity-body. - - - - - Equivalent to status code 205. - Indicates that the server has fulfilled the client's request, and the user agent should - reset the document view which caused the request to be sent. - - - - - Equivalent to status code 206. - Indicates that the server has fulfilled the partial GET request for the resource. - - - - - - Equivalent to status code 300. - Indicates that the requested resource corresponds to any of multiple representations. - - - MultipleChoices is a synonym for Ambiguous. - - - - - - - Equivalent to status code 300. - Indicates that the requested resource corresponds to any of multiple representations. - - - Ambiguous is a synonym for MultipleChoices. - - - - - - - Equivalent to status code 301. - Indicates that the requested resource has been assigned a new permanent URI and - any future references to this resource should use one of the returned URIs. - - - MovedPermanently is a synonym for Moved. - - - - - - - Equivalent to status code 301. - Indicates that the requested resource has been assigned a new permanent URI and - any future references to this resource should use one of the returned URIs. - - - Moved is a synonym for MovedPermanently. - - - - - - - Equivalent to status code 302. - Indicates that the requested resource is located temporarily under a different URI. - - - Found is a synonym for Redirect. - - - - - - - Equivalent to status code 302. - Indicates that the requested resource is located temporarily under a different URI. - - - Redirect is a synonym for Found. - - - - - - - Equivalent to status code 303. - Indicates that the response to the request can be found under a different URI and - should be retrieved using a GET method on that resource. - - - SeeOther is a synonym for RedirectMethod. - - - - - - - Equivalent to status code 303. - Indicates that the response to the request can be found under a different URI and - should be retrieved using a GET method on that resource. - - - RedirectMethod is a synonym for SeeOther. - - - - - - Equivalent to status code 304. - Indicates that the client has performed a conditional GET request and access is allowed, - but the document hasn't been modified. - - - - - Equivalent to status code 305. - Indicates that the requested resource must be accessed through the proxy given by - the Location field. - - - - - Equivalent to status code 306. - This status code was used in a previous version of the specification, is no longer used, - and is reserved for future use. - - - - - - Equivalent to status code 307. - Indicates that the requested resource is located temporarily under a different URI. - - - TemporaryRedirect is a synonym for RedirectKeepVerb. - - - - - - - Equivalent to status code 307. - Indicates that the requested resource is located temporarily under a different URI. - - - RedirectKeepVerb is a synonym for TemporaryRedirect. - - - - - - Equivalent to status code 400. - Indicates that the client's request couldn't be understood by the server due to - malformed syntax. - - - - - Equivalent to status code 401. - Indicates that the client's request requires user authentication. - - - - - Equivalent to status code 402. - This status code is reserved for future use. - - - - - Equivalent to status code 403. - Indicates that the server understood the client's request but is refusing to fulfill it. - - - - - Equivalent to status code 404. - Indicates that the server hasn't found anything matching the request URI. - - - - - Equivalent to status code 405. - Indicates that the method specified in the request line isn't allowed for the resource - identified by the request URI. - - - - - Equivalent to status code 406. - Indicates that the server doesn't have the appropriate resource to respond to the Accept - headers in the client's request. - - - - - Equivalent to status code 407. - Indicates that the client must first authenticate itself with the proxy. - - - - - Equivalent to status code 408. - Indicates that the client didn't produce a request within the time that the server was - prepared to wait. - - - - - Equivalent to status code 409. - Indicates that the client's request couldn't be completed due to a conflict on the server. - - - - - Equivalent to status code 410. - Indicates that the requested resource is no longer available at the server and - no forwarding address is known. - - - - - Equivalent to status code 411. - Indicates that the server refuses to accept the client's request without a defined - Content-Length. - - - - - Equivalent to status code 412. - Indicates that the precondition given in one or more of the request headers evaluated to - false when it was tested on the server. - - - - - Equivalent to status code 413. - Indicates that the entity of the client's request is larger than the server is willing or - able to process. - - - - - Equivalent to status code 414. - Indicates that the request URI is longer than the server is willing to interpret. - - - - - Equivalent to status code 415. - Indicates that the entity of the client's request is in a format not supported by - the requested resource for the requested method. - - - - - Equivalent to status code 416. - Indicates that none of the range specifier values in a Range request header overlap - the current extent of the selected resource. - - - - - Equivalent to status code 417. - Indicates that the expectation given in an Expect request header couldn't be met by - the server. - - - - - Equivalent to status code 500. - Indicates that the server encountered an unexpected condition which prevented it from - fulfilling the client's request. - - - - - Equivalent to status code 501. - Indicates that the server doesn't support the functionality required to fulfill the client's - request. - - - - - Equivalent to status code 502. - Indicates that a gateway or proxy server received an invalid response from the upstream - server. - - - - - Equivalent to status code 503. - Indicates that the server is currently unable to handle the client's request due to - a temporary overloading or maintenance of the server. - - - - - Equivalent to status code 504. - Indicates that a gateway or proxy server didn't receive a timely response from the upstream - server or some other auxiliary server. - - - - - Equivalent to status code 505. - Indicates that the server doesn't support the HTTP version used in the client's request. - - - - - Exposes the methods and properties used to access the information in a WebSocket service - provided by the or . - - - The WebSocketServiceHost class is an abstract class. - - - - - Initializes a new instance of the class. - - - - - Creates a new session in the WebSocket service. - - - A instance that represents a new session. - - - - - Gets or sets a value indicating whether the WebSocket service cleans up - the inactive sessions periodically. - - - true if the service cleans up the inactive sessions periodically; - otherwise, false. - - - - - Gets the path to the WebSocket service. - - - A that represents the absolute path to the service. - - - - - Gets the access to the sessions in the WebSocket service. - - - A that manages the sessions in the service. - - - - - Gets the of the behavior of the WebSocket service. - - - A that represents the type of the behavior of the service. - - - - - Gets or sets the wait time for the response to the WebSocket Ping or Close. - - - A that represents the wait time. The default value is - the same as 1 second. - - - - - Contains the values of the status code for the WebSocket connection close. - - - - The values of the status code are defined in - Section 7.4 of RFC 6455. - - - "Reserved value" must not be set as a status code in a close control frame by - an endpoint. It's designated for use in applications expecting a status code to - indicate that the connection was closed due to the system grounds. - - - - - - Equivalent to close status 1000. - Indicates a normal close. - - - - - Equivalent to close status 1001. - Indicates that an endpoint is going away. - - - - - Equivalent to close status 1002. - Indicates that an endpoint is terminating the connection due to a protocol error. - - - - - Equivalent to close status 1003. - Indicates that an endpoint is terminating the connection because it has received - a type of data that it cannot accept. - - - - - Equivalent to close status 1004. - Still undefined. A Reserved value. - - - - - Equivalent to close status 1005. - Indicates that no status code was actually present. A Reserved value. - - - - - Equivalent to close status 1006. - Indicates that the connection was closed abnormally. A Reserved value. - - - - - Equivalent to close status 1007. - Indicates that an endpoint is terminating the connection because it has received - a message that contains data that isn't consistent with the type of the message. - - - - - Equivalent to close status 1008. - Indicates that an endpoint is terminating the connection because it has received - a message that violates its policy. - - - - - Equivalent to close status 1009. - Indicates that an endpoint is terminating the connection because it has received - a message that is too big to process. - - - - - Equivalent to close status 1010. - Indicates that a client is terminating the connection because it has expected - the server to negotiate one or more extension, but the server didn't return - them in the handshake response. - - - - - Equivalent to close status 1011. - Indicates that a server is terminating the connection because it has encountered - an unexpected condition that prevented it from fulfilling the request. - - - - - Equivalent to close status 1015. - Indicates that the connection was closed due to a failure to perform a TLS handshake. - A Reserved value. - - - - - Contains the values of the opcode that indicates the type of a WebSocket frame. - - - The values of the opcode are defined in - Section 5.2 of RFC 6455. - - - - - Equivalent to numeric value 0. - Indicates a continuation frame. - - - - - Equivalent to numeric value 1. - Indicates a text frame. - - - - - Equivalent to numeric value 2. - Indicates a binary frame. - - - - - Equivalent to numeric value 8. - Indicates a connection close frame. - - - - - Equivalent to numeric value 9. - Indicates a ping frame. - - - - - Equivalent to numeric value 10. - Indicates a pong frame. - - - - - Provides the properties used to access the information in a WebSocket connection request - received by the . - - - - - Exposes the properties used to access the information in a WebSocket connection request. - - - The WebSocketContext class is an abstract class. - - - - - Initializes a new instance of the class. - - - - - Gets the HTTP cookies included in the request. - - - A that contains the cookies. - - - - - Gets the HTTP headers included in the request. - - - A that contains the headers. - - - - - Gets the value of the Host header included in the request. - - - A that represents the value of the Host header. - - - - - Gets a value indicating whether the client is authenticated. - - - true if the client is authenticated; otherwise, false. - - - - - Gets a value indicating whether the client connected from the local computer. - - - true if the client connected from the local computer; otherwise, false. - - - - - Gets a value indicating whether the WebSocket connection is secured. - - - true if the connection is secured; otherwise, false. - - - - - Gets a value indicating whether the request is a WebSocket connection request. - - - true if the request is a WebSocket connection request; otherwise, false. - - - - - Gets the value of the Origin header included in the request. - - - A that represents the value of the Origin header. - - - - - Gets the query string included in the request. - - - A that contains the query string parameters. - - - - - Gets the URI requested by the client. - - - A that represents the requested URI. - - - - - Gets the value of the Sec-WebSocket-Key header included in the request. - - - This property provides a part of the information used by the server to prove that it - received a valid WebSocket connection request. - - - A that represents the value of the Sec-WebSocket-Key header. - - - - - Gets the values of the Sec-WebSocket-Protocol header included in the request. - - - This property represents the subprotocols requested by the client. - - - An instance that provides - an enumerator which supports the iteration over the values of the Sec-WebSocket-Protocol - header. - - - - - Gets the value of the Sec-WebSocket-Version header included in the request. - - - This property represents the WebSocket protocol version. - - - A that represents the value of the Sec-WebSocket-Version header. - - - - - Gets the server endpoint as an IP address and a port number. - - - A that represents the server endpoint. - - - - - Gets the client information (identity, authentication, and security roles). - - - A instance that represents the client information. - - - - - Gets the client endpoint as an IP address and a port number. - - - A that represents the client endpoint. - - - - - Gets the instance used for two-way communication - between client and server. - - - A . - - - - - Returns a that represents the current - . - - - A that represents the current - . - - - - - Gets the HTTP cookies included in the request. - - - A that contains the cookies. - - - - - Gets the HTTP headers included in the request. - - - A that contains the headers. - - - - - Gets the value of the Host header included in the request. - - - A that represents the value of the Host header. - - - - - Gets a value indicating whether the client is authenticated. - - - true if the client is authenticated; otherwise, false. - - - - - Gets a value indicating whether the client connected from the local computer. - - - true if the client connected from the local computer; otherwise, false. - - - - - Gets a value indicating whether the WebSocket connection is secured. - - - true if the connection is secured; otherwise, false. - - - - - Gets a value indicating whether the request is a WebSocket connection request. - - - true if the request is a WebSocket connection request; otherwise, false. - - - - - Gets the value of the Origin header included in the request. - - - A that represents the value of the Origin header. - - - - - Gets the query string included in the request. - - - A that contains the query string parameters. - - - - - Gets the URI requested by the client. - - - A that represents the requested URI. - - - - - Gets the value of the Sec-WebSocket-Key header included in the request. - - - This property provides a part of the information used by the server to prove that it - received a valid WebSocket connection request. - - - A that represents the value of the Sec-WebSocket-Key header. - - - - - Gets the values of the Sec-WebSocket-Protocol header included in the request. - - - This property represents the subprotocols requested by the client. - - - An instance that provides - an enumerator which supports the iteration over the values of the Sec-WebSocket-Protocol - header. - - - - - Gets the value of the Sec-WebSocket-Version header included in the request. - - - This property represents the WebSocket protocol version. - - - A that represents the value of the Sec-WebSocket-Version header. - - - - - Gets the server endpoint as an IP address and a port number. - - - A that represents the server endpoint. - - - - - Gets the client information (identity, authentication, and security roles). - - - A instance that represents the client information. - - - - - Gets the client endpoint as an IP address and a port number. - - - A that represents the client endpoint. - - - - - Gets the instance used for two-way communication - between client and server. - - - A . - - - - - Provides the properties used to access the information in a WebSocket connection request - received by the . - - - - - Returns a that represents the current - . - - - A that represents the current - . - - - - - Gets the HTTP cookies included in the request. - - - A that contains the cookies. - - - - - Gets the HTTP headers included in the request. - - - A that contains the headers. - - - - - Gets the value of the Host header included in the request. - - - A that represents the value of the Host header. - - - - - Gets a value indicating whether the client is authenticated. - - - true if the client is authenticated; otherwise, false. - - - - - Gets a value indicating whether the client connected from the local computer. - - - true if the client connected from the local computer; otherwise, false. - - - - - Gets a value indicating whether the WebSocket connection is secured. - - - true if the connection is secured; otherwise, false. - - - - - Gets a value indicating whether the request is a WebSocket connection request. - - - true if the request is a WebSocket connection request; otherwise, false. - - - - - Gets the value of the Origin header included in the request. - - - A that represents the value of the Origin header. - - - - - Gets the query string included in the request. - - - A that contains the query string parameters. - - - - - Gets the URI requested by the client. - - - A that represents the requested URI. - - - - - Gets the value of the Sec-WebSocket-Key header included in the request. - - - This property provides a part of the information used by the server to prove that it - received a valid WebSocket connection request. - - - A that represents the value of the Sec-WebSocket-Key header. - - - - - Gets the values of the Sec-WebSocket-Protocol header included in the request. - - - This property represents the subprotocols requested by the client. - - - An instance that provides - an enumerator which supports the iteration over the values of the Sec-WebSocket-Protocol - header. - - - - - Gets the value of the Sec-WebSocket-Version header included in the request. - - - This property represents the WebSocket protocol version. - - - A that represents the value of the Sec-WebSocket-Version header. - - - - - Gets the server endpoint as an IP address and a port number. - - - A that represents the server endpoint. - - - - - Gets the client information (identity, authentication, and security roles). - - - A instance that represents the client information. - - - - - Gets the client endpoint as an IP address and a port number. - - - A that represents the client endpoint. - - - - - Gets the instance used for two-way communication - between client and server. - - - A . - - - - - Contains the event data associated with an HTTP request event that - the emits. - - - - An HTTP request event occurs when the receives an HTTP request. - - - If you would like to get the request data, you should access - the property. - - - And if you would like to get the data used to return a response, you should access - the property. - - - - - - Gets the that represents the HTTP request sent from - a client. - - - A that represents the request. - - - - - Gets the used to return an HTTP response to the client. - - - A used to return a response. - - - - - Contains the values of the compression method used to compress the message on the WebSocket - connection. - - - The values of the compression method are defined in - Compression - Extensions for WebSocket. - - - - - Indicates non compression. - - - - - Indicates using DEFLATE. - - - - - The exception that is thrown when a gets a fatal error. - - - - - Gets the status code indicating the cause of the exception. - - - One of the enum values, represents the status code - indicating the cause of the exception. - - - - - Represents a log data used by the class. - - - - - Returns a that represents the current . - - - A that represents the current . - - - - - Gets the information of the logging method caller. - - - A that provides the information of the logging method caller. - - - - - Gets the date and time when the log data was created. - - - A that represents the date and time when the log data was created. - - - - - Gets the logging level of the log data. - - - One of the enum values, indicates the logging level of the log data. - - - - - Gets the message of the log data. - - - A that represents the message of the log data. - - - - - Contains the values of the logging level. - - - - - Indicates the bottom logging level. - - - - - Indicates the 2nd logging level from the bottom. - - - - - Indicates the 3rd logging level from the bottom. - - - - - Indicates the 3rd logging level from the top. - - - - - Indicates the 2nd logging level from the top. - - - - - Indicates the top logging level. - - - - - Provides a set of methods and properties for logging. - - - - If you output a log with lower than the , - it cannot be outputted. - - - The default output action writes a log to the standard output stream and - the if it has a valid path. - - - If you would like to use the custom output action, you should set the - to any Action<LogData, string> delegate. - - - - - - Initializes a new instance of the class. - - - This constructor initializes the current logging level with . - - - - - Initializes a new instance of the class with the specified - logging . - - - One of the enum values. - - - - - Initializes a new instance of the class with the specified - logging , path to the log , and - action. - - - One of the enum values. - - - A that represents the path to the log file. - - - An Action<LogData, string> delegate that references the method(s) - used to output a log. A parameter passed to this delegate - is . - - - - - Outputs as a log with . - - - If the current logging level is higher than , - this method doesn't output as a log. - - - A that represents the message to output as a log. - - - - - Outputs as a log with . - - - If the current logging level is higher than , - this method doesn't output as a log. - - - A that represents the message to output as a log. - - - - - Outputs as a log with . - - - A that represents the message to output as a log. - - - - - Outputs as a log with . - - - If the current logging level is higher than , - this method doesn't output as a log. - - - A that represents the message to output as a log. - - - - - Outputs as a log with . - - - If the current logging level is higher than , - this method doesn't output as a log. - - - A that represents the message to output as a log. - - - - - Outputs as a log with . - - - If the current logging level is higher than , - this method doesn't output as a log. - - - A that represents the message to output as a log. - - - - - Gets or sets the current path to the log file. - - - A that represents the current path to the log file if any. - - - - - Gets or sets the current logging level. - - - A log with lower than the value of this property cannot be outputted. - - - One of the enum values, indicates the current logging level. - - - - - Gets or sets the current output action used to output a log. - - - - An Action<LogData, string> delegate that references the method(s) used to - output a log. A parameter passed to this delegate is the value of - the . - - - If the value to set is , the current output action is changed to - the default output action. - - - - - - Contains the values of the state of the WebSocket connection. - - - The values of the state are defined in - The WebSocket API. - - - - - Equivalent to numeric value 0. - Indicates that the connection hasn't yet been established. - - - - - Equivalent to numeric value 1. - Indicates that the connection is established and the communication is possible. - - - - - Equivalent to numeric value 2. - Indicates that the connection is going through the closing handshake or - the WebSocket.Close method has been invoked. - - - - - Equivalent to numeric value 3. - Indicates that the connection has been closed or couldn't be opened. - - - - - Exposes the properties used to access the information in a session in a WebSocket service. - - - - - Gets the information in the connection request to the WebSocket service. - - - A that provides the access to the connection request. - - - - - Gets the unique ID of the session. - - - A that represents the unique ID of the session. - - - - - Gets the WebSocket subprotocol used in the session. - - - A that represents the subprotocol if any. - - - - - Gets the time that the session has started. - - - A that represents the time that the session has started. - - - - - Gets the state of the used in the session. - - - One of the enum values, indicates the state of - the used in the session. - - - - - Manages the sessions in a Websocket service. - - - - - Sends binary to every client in the WebSocket service. - - - An array of that represents the binary data to send. - - - - - Sends text to every client in the WebSocket service. - - - A that represents the text data to send. - - - - - Sends binary asynchronously to every client in - the WebSocket service. - - - This method doesn't wait for the send to be complete. - - - An array of that represents the binary data to send. - - - An delegate that references the method(s) called when - the send is complete. - - - - - Sends text asynchronously to every client in - the WebSocket service. - - - This method doesn't wait for the send to be complete. - - - A that represents the text data to send. - - - An delegate that references the method(s) called when - the send is complete. - - - - - Sends binary data from the specified asynchronously to - every client in the WebSocket service. - - - This method doesn't wait for the send to be complete. - - - A from which contains the binary data to send. - - - An that represents the number of bytes to send. - - - An delegate that references the method(s) called when - the send is complete. - - - - - Sends a Ping to every client in the WebSocket service. - - - A Dictionary<string, bool> that contains a collection of pairs of - a session ID and a value indicating whether the manager received a Pong from - each client in a time. - - - - - Sends a Ping with the specified to every client in - the WebSocket service. - - - A Dictionary<string, bool> that contains a collection of pairs of - a session ID and a value indicating whether the manager received a Pong from - each client in a time. - - - A that represents the message to send. - - - - - Closes the session with the specified . - - - A that represents the ID of the session to close. - - - - - Closes the session with the specified , , - and . - - - A that represents the ID of the session to close. - - - A that represents the status code indicating the reason for the close. - - - A that represents the reason for the close. - - - - - Closes the session with the specified , , - and . - - - A that represents the ID of the session to close. - - - One of the enum values, represents the status code - indicating the reason for the close. - - - A that represents the reason for the close. - - - - - Sends a Ping to the client on the session with the specified . - - - true if the manager receives a Pong from the client in a time; - otherwise, false. - - - A that represents the ID of the session to find. - - - - - Sends a Ping with the specified to the client on - the session with the specified . - - - true if the manager receives a Pong from the client in a time; - otherwise, false. - - - A that represents the message to send. - - - A that represents the ID of the session to find. - - - - - Sends binary to the client on the session with - the specified . - - - An array of that represents the binary data to send. - - - A that represents the ID of the session to find. - - - - - Sends text to the client on the session with - the specified . - - - A that represents the text data to send. - - - A that represents the ID of the session to find. - - - - - Sends binary asynchronously to the client on - the session with the specified . - - - This method doesn't wait for the send to be complete. - - - An array of that represents the binary data to send. - - - A that represents the ID of the session to find. - - - An Action<bool> delegate that references the method(s) called when - the send is complete. A passed to this delegate is true - if the send is complete successfully. - - - - - Sends text asynchronously to the client on - the session with the specified . - - - This method doesn't wait for the send to be complete. - - - A that represents the text data to send. - - - A that represents the ID of the session to find. - - - An Action<bool> delegate that references the method(s) called when - the send is complete. A passed to this delegate is true - if the send is complete successfully. - - - - - Sends binary data from the specified asynchronously to - the client on the session with the specified . - - - This method doesn't wait for the send to be complete. - - - A from which contains the binary data to send. - - - An that represents the number of bytes to send. - - - A that represents the ID of the session to find. - - - An Action<bool> delegate that references the method(s) called when - the send is complete. A passed to this delegate is true - if the send is complete successfully. - - - - - Cleans up the inactive sessions in the WebSocket service. - - - - - Tries to get the session with the specified . - - - true if the session is successfully found; otherwise, false. - - - A that represents the ID of the session to find. - - - When this method returns, a instance that - provides the access to the information in the session, or - if it's not found. This parameter is passed uninitialized. - - - - - Gets the IDs for the active sessions in the Websocket service. - - - An IEnumerable<string> instance that provides an enumerator which - supports the iteration over the collection of the IDs for the active sessions. - - - - - Gets the number of the sessions in the Websocket service. - - - An that represents the number of the sessions. - - - - - Gets the IDs for the sessions in the Websocket service. - - - An IEnumerable<string> instance that provides an enumerator which - supports the iteration over the collection of the IDs for the sessions. - - - - - Gets the IDs for the inactive sessions in the Websocket service. - - - An IEnumerable<string> instance that provides an enumerator which - supports the iteration over the collection of the IDs for the inactive sessions. - - - - - Gets the session with the specified . - - - A instance that provides the access to - the information in the session, or if it's not found. - - - A that represents the ID of the session to find. - - - - - Gets a value indicating whether the manager cleans up the inactive sessions in - the WebSocket service periodically. - - - true if the manager cleans up the inactive sessions every 60 seconds; - otherwise, false. - - - - - Gets the sessions in the Websocket service. - - - An IEnumerable<IWebSocketSession> instance that provides an enumerator - which supports the iteration over the collection of the sessions in the service. - - - - - Gets the wait time for the response to the WebSocket Ping or Close. - - - A that represents the wait time. - - - - - Holds the user name and password from the HTTP Basic authentication credentials. - - - - - Gets the password from the HTTP Basic authentication credentials. - - - A that represents the password. - - - - - Holds the user name and other parameters from the HTTP Digest authentication credentials. - - - - - Gets the algorithm parameter from the HTTP Digest authentication credentials. - - - A that represents the algorithm parameter. - - - - - Gets the cnonce parameter from the HTTP Digest authentication credentials. - - - A that represents the cnonce parameter. - - - - - Gets the nc parameter from the HTTP Digest authentication credentials. - - - A that represents the nc parameter. - - - - - Gets the nonce parameter from the HTTP Digest authentication credentials. - - - A that represents the nonce parameter. - - - - - Gets the opaque parameter from the HTTP Digest authentication credentials. - - - A that represents the opaque parameter. - - - - - Gets the qop parameter from the HTTP Digest authentication credentials. - - - A that represents the qop parameter. - - - - - Gets the realm parameter from the HTTP Digest authentication credentials. - - - A that represents the realm parameter. - - - - - Gets the response parameter from the HTTP Digest authentication credentials. - - - A that represents the response parameter. - - - - - Gets the uri parameter from the HTTP Digest authentication credentials. - - - A that represents the uri parameter. - - - - - Provides the credentials for HTTP authentication (Basic/Digest). - - - - - Initializes a new instance of the class - with the specified user name and password. - - - A that represents the user name associated with the - credentials. - - - A that represents the password for the user name - associated with the credentials. - - - is or empty. - - - - - Initializes a new instance of the class - with the specified user name, password, domain, and roles. - - - A that represents the user name associated with the - credentials. - - - A that represents the password for the user name - associated with the credentials. - - - A that represents the name of the user domain - associated with the credentials. - - - An array of that contains the role names to which - the user associated with the credentials belongs if any. - - - is or empty. - - - - - Gets the name of the user domain associated with the credentials. - - - A that represents the name of the user domain - associated with the credentials. - - - - - Gets the password for the user name associated with the credentials. - - - A that represents the password for the user name - associated with the credentials. - - - - - Gets the role names to which the user associated with the credentials - belongs. - - - An array of that contains the role names to which - the user associated with the credentials belongs. - - - - - Gets the user name associated with the credentials. - - - A that represents the user name associated with the - credentials. - - - - - Manages the WebSocket services provided by the or - . - - - - - Sends binary to every client in the WebSocket services. - - - An array of that represents the binary data to send. - - - - - Sends text to every client in the WebSocket services. - - - A that represents the text data to send. - - - - - Sends binary asynchronously to every client in - the WebSocket services. - - - This method doesn't wait for the send to be complete. - - - An array of that represents the binary data to send. - - - An delegate that references the method(s) called when - the send is complete. - - - - - Sends text asynchronously to every client in - the WebSocket services. - - - This method doesn't wait for the send to be complete. - - - A that represents the text data to send. - - - An delegate that references the method(s) called when - the send is complete. - - - - - Sends binary data from the specified asynchronously to - every client in the WebSocket services. - - - This method doesn't wait for the send to be complete. - - - A from which contains the binary data to send. - - - An that represents the number of bytes to send. - - - An delegate that references the method(s) called when - the send is complete. - - - - - Sends a Ping to every client in the WebSocket services. - - - A Dictionary<string, Dictionary<string, bool>> that contains - a collection of pairs of a service path and a collection of pairs of a session ID - and a value indicating whether the manager received a Pong from each client in a time, - or if this method isn't available. - - - - - Sends a Ping with the specified to every client in - the WebSocket services. - - - A Dictionary<string, Dictionary<string, bool>> that contains - a collection of pairs of a service path and a collection of pairs of a session ID - and a value indicating whether the manager received a Pong from each client in a time, - or if this method isn't available or - is invalid. - - - A that represents the message to send. - - - - - Tries to get the WebSocket service host with the specified . - - - true if the service is successfully found; otherwise, false. - - - A that represents the absolute path to the service to find. - - - When this method returns, a instance that - provides the access to the information in the service, or - if it's not found. This parameter is passed uninitialized. - - - - - Gets the number of the WebSocket services. - - - An that represents the number of the services. - - - - - Gets the host instances for the Websocket services. - - - An IEnumerable<WebSocketServiceHost> instance that provides an enumerator - which supports the iteration over the collection of the host instances for the services. - - - - - Gets the WebSocket service host with the specified . - - - A instance that provides the access to - the information in the service, or if it's not found. - - - A that represents the absolute path to the service to find. - - - - - Gets a value indicating whether the manager cleans up the inactive sessions - in the WebSocket services periodically. - - - true if the manager cleans up the inactive sessions every 60 seconds; - otherwise, false. - - - - - Gets the paths for the WebSocket services. - - - An IEnumerable<string> instance that provides an enumerator which supports - the iteration over the collection of the paths for the services. - - - - - Gets the total number of the sessions in the WebSocket services. - - - An that represents the total number of the sessions in the services. - - - - - Gets the wait time for the response to the WebSocket Ping or Close. - - - A that represents the wait time. - - - - - Exposes the methods and properties used to define the behavior of a WebSocket service - provided by the or . - - - The WebSocketBehavior class is an abstract class. - - - - - Initializes a new instance of the class. - - - - - Calls the method with the specified and - . - - - This method doesn't call the method if is - or empty. - - - A that represents the error message. - - - An instance that represents the cause of the error if any. - - - - - Called when the WebSocket connection used in a session has been closed. - - - A that represents the event data passed to - a event. - - - - - Called when the used in a session gets an error. - - - A that represents the event data passed to - a event. - - - - - Called when the used in a session receives a message. - - - A that represents the event data passed to - a event. - - - - - Called when the WebSocket connection used in a session has been established. - - - - - Sends binary to the client on a session. - - - This method is available after the WebSocket connection has been established. - - - An array of that represents the binary data to send. - - - - - Sends the specified as binary data to the client on a session. - - - This method is available after the WebSocket connection has been established. - - - A that represents the file to send. - - - - - Sends text to the client on a session. - - - This method is available after the WebSocket connection has been established. - - - A that represents the text data to send. - - - - - Sends binary asynchronously to the client on a session. - - - - This method is available after the WebSocket connection has been established. - - - This method doesn't wait for the send to be complete. - - - - An array of that represents the binary data to send. - - - An Action<bool> delegate that references the method(s) called when - the send is complete. A passed to this delegate is true - if the send is complete successfully. - - - - - Sends the specified as binary data asynchronously to - the client on a session. - - - - This method is available after the WebSocket connection has been established. - - - This method doesn't wait for the send to be complete. - - - - A that represents the file to send. - - - An Action<bool> delegate that references the method(s) called when - the send is complete. A passed to this delegate is true - if the send is complete successfully. - - - - - Sends text asynchronously to the client on a session. - - - - This method is available after the WebSocket connection has been established. - - - This method doesn't wait for the send to be complete. - - - - A that represents the text data to send. - - - An Action<bool> delegate that references the method(s) called when - the send is complete. A passed to this delegate is true - if the send is complete successfully. - - - - - Sends binary data from the specified asynchronously to - the client on a session. - - - - This method is available after the WebSocket connection has been established. - - - This method doesn't wait for the send to be complete. - - - - A from which contains the binary data to send. - - - An that represents the number of bytes to send. - - - An Action<bool> delegate that references the method(s) called when - the send is complete. A passed to this delegate is true - if the send is complete successfully. - - - - - Gets the logging functions. - - - A that provides the logging functions, - or if the WebSocket connection isn't established. - - - - - Gets the access to the sessions in the WebSocket service. - - - A that provides the access to the sessions, - or if the WebSocket connection isn't established. - - - - - Gets the information in a connection request to the WebSocket service. - - - A that provides the access to the connection request, - or if the WebSocket connection isn't established. - - - - - Gets or sets the delegate called to validate the HTTP cookies included in - a connection request to the WebSocket service. - - - This delegate is called when the used in a session validates - the connection request. - - - - A Func<CookieCollection, CookieCollection, bool> delegate that references - the method(s) used to validate the cookies. 1st passed to - this delegate contains the cookies to validate if any. 2nd - passed to this delegate receives the cookies to send to the client. - - - This delegate should return true if the cookies are valid. - - - The default value is , and it does nothing to validate. - - - - - - Gets or sets a value indicating whether the used in a session emits - a event when receives a Ping. - - - true if the emits a event - when receives a Ping; otherwise, false. The default value is false. - - - - - Gets the unique ID of a session. - - - A that represents the unique ID of the session, - or if the WebSocket connection isn't established. - - - - - Gets or sets a value indicating whether the WebSocket service ignores - the Sec-WebSocket-Extensions header included in a connection request. - - - true if the WebSocket service ignores the extensions; - otherwise, false. The default value is false. - - - - - Gets or sets the delegate called to validate the Origin header included in - a connection request to the WebSocket service. - - - This delegate is called when the used in a session validates - the connection request. - - - - A Func<string, bool> delegate that references the method(s) used to validate - the origin header. A passed to this delegate represents the value of - the origin header to validate if any. - - - This delegate should return true if the origin header is valid. - - - The default value is , and it does nothing to validate. - - - - - - Gets or sets the WebSocket subprotocol used in the WebSocket service. - - - Set operation of this property is available before the WebSocket connection has - been established. - - - - A that represents the subprotocol if any. - The default value is . - - - The value to set must be a token defined in - RFC 2616. - - - - - - Gets the time that a session has started. - - - A that represents the time that the session has started, - or if the WebSocket connection isn't established. - - - - - Gets the state of the used in a session. - - - One of the enum values, indicates the state of - the . - - - - - Stores the parameters used to configure a instance as a client. - - - - - Stores the parameters used to configure a instance. - - - The SslConfiguration class is an abstract class. - - - - - Initializes a new instance of the class with - the specified and - . - - - The enum value that represents the protocols used for - authentication. - - - true if the certificate revocation list is checked during authentication; - otherwise, false. - - - - - Gets or sets the callback used to select a certificate to supply to the remote party. - - - If this callback returns , no certificate will be supplied. - - - A delegate that references the method - used to select a certificate. The default value is a function that only returns - . - - - - - Gets or sets the callback used to validate the certificate supplied by the remote party. - - - If this callback returns true, the certificate will be valid. - - - A delegate that references the method - used to validate the certificate. The default value is a function that only returns - true. - - - - - Gets or sets a value indicating whether the certificate revocation list is checked - during authentication. - - - true if the certificate revocation list is checked; otherwise, false. - - - - - Gets or sets the SSL protocols used for authentication. - - - The enum value that represents the protocols used for - authentication. - - - - - Initializes a new instance of the class with - the specified . - - - A that represents the name of the server that shares - a secure connection. - - - - - Initializes a new instance of the class with - the specified , , - , and . - - - A that represents the name of the server that shares - a secure connection. - - - A that contains client certificates. - - - The enum value that represents the protocols used for - authentication. - - - true if the certificate revocation list is checked during authentication; - otherwise, false. - - - - - Gets or sets the collection that contains client certificates. - - - A that contains client certificates. - - - - - Gets or sets the callback used to select a client certificate to supply to the server. - - - If this callback returns , no client certificate will be supplied. - - - A delegate that references the method - used to select the client certificate. The default value is a function that only returns - . - - - - - Gets or sets the callback used to validate the certificate supplied by the server. - - - If this callback returns true, the server certificate will be valid. - - - A delegate that references the method - used to validate the server certificate. The default value is a function that only returns - true. - - - - - Gets or sets the name of the server that shares a secure connection. - - - A that represents the name of the server that shares - a secure connection. - - - - - Stores the parameters used to configure a instance as a server. - - - - - Initializes a new instance of the class with - the specified . - - - A that represents the certificate used to authenticate - the server. - - - - - Initializes a new instance of the class with - the specified , - , , - and . - - - A that represents the certificate used to authenticate - the server. - - - true if the client must supply a certificate for authentication; - otherwise, false. - - - The enum value that represents the protocols used for - authentication. - - - true if the certificate revocation list is checked during authentication; - otherwise, false. - - - - - Gets or sets a value indicating whether the client must supply a certificate for - authentication. - - - true if the client must supply a certificate; otherwise, false. - - - - - Gets or sets the callback used to validate the certificate supplied by the client. - - - If this callback returns true, the client certificate will be valid. - - - A delegate that references the method - used to validate the client certificate. The default value is a function that only returns - true. - - - - - Gets or sets the certificate used to authenticate the server for secure connection. - - - A that represents the certificate used to authenticate - the server. - - - - - Contains the HTTP headers that may be specified in a client request. - - - The HttpRequestHeader enumeration contains the HTTP request headers defined in - RFC 2616 for the HTTP/1.1 and - RFC 6455 for the WebSocket. - - - - - Indicates the Cache-Control header. - - - - - Indicates the Connection header. - - - - - Indicates the Date header. - - - - - Indicates the Keep-Alive header. - - - - - Indicates the Pragma header. - - - - - Indicates the Trailer header. - - - - - Indicates the Transfer-Encoding header. - - - - - Indicates the Upgrade header. - - - - - Indicates the Via header. - - - - - Indicates the Warning header. - - - - - Indicates the Allow header. - - - - - Indicates the Content-Length header. - - - - - Indicates the Content-Type header. - - - - - Indicates the Content-Encoding header. - - - - - Indicates the Content-Language header. - - - - - Indicates the Content-Location header. - - - - - Indicates the Content-MD5 header. - - - - - Indicates the Content-Range header. - - - - - Indicates the Expires header. - - - - - Indicates the Last-Modified header. - - - - - Indicates the Accept header. - - - - - Indicates the Accept-Charset header. - - - - - Indicates the Accept-Encoding header. - - - - - Indicates the Accept-Language header. - - - - - Indicates the Authorization header. - - - - - Indicates the Cookie header. - - - - - Indicates the Expect header. - - - - - Indicates the From header. - - - - - Indicates the Host header. - - - - - Indicates the If-Match header. - - - - - Indicates the If-Modified-Since header. - - - - - Indicates the If-None-Match header. - - - - - Indicates the If-Range header. - - - - - Indicates the If-Unmodified-Since header. - - - - - Indicates the Max-Forwards header. - - - - - Indicates the Proxy-Authorization header. - - - - - Indicates the Referer header. - - - - - Indicates the Range header. - - - - - Indicates the TE header. - - - - - Indicates the Translate header. - - - - - Indicates the User-Agent header. - - - - - Indicates the Sec-WebSocket-Key header. - - - - - Indicates the Sec-WebSocket-Extensions header. - - - - - Indicates the Sec-WebSocket-Protocol header. - - - - - Indicates the Sec-WebSocket-Version header. - - - - - Contains the HTTP headers that can be specified in a server response. - - - The HttpResponseHeader enumeration contains the HTTP response headers defined in - RFC 2616 for the HTTP/1.1 and - RFC 6455 for the WebSocket. - - - - - Indicates the Cache-Control header. - - - - - Indicates the Connection header. - - - - - Indicates the Date header. - - - - - Indicates the Keep-Alive header. - - - - - Indicates the Pragma header. - - - - - Indicates the Trailer header. - - - - - Indicates the Transfer-Encoding header. - - - - - Indicates the Upgrade header. - - - - - Indicates the Via header. - - - - - Indicates the Warning header. - - - - - Indicates the Allow header. - - - - - Indicates the Content-Length header. - - - - - Indicates the Content-Type header. - - - - - Indicates the Content-Encoding header. - - - - - Indicates the Content-Language header. - - - - - Indicates the Content-Location header. - - - - - Indicates the Content-MD5 header. - - - - - Indicates the Content-Range header. - - - - - Indicates the Expires header. - - - - - Indicates the Last-Modified header. - - - - - Indicates the Accept-Ranges header. - - - - - Indicates the Age header. - - - - - Indicates the ETag header. - - - - - Indicates the Location header. - - - - - Indicates the Proxy-Authenticate header. - - - - - Indicates the Retry-After header. - - - - - Indicates the Server header. - - - - - Indicates the Set-Cookie header. - - - - - Indicates the Vary header. - - - - - Indicates the WWW-Authenticate header. - - - - - Indicates the Sec-WebSocket-Extensions header. - - - - - Indicates the Sec-WebSocket-Accept header. - - - - - Indicates the Sec-WebSocket-Protocol header. - - - - - Indicates the Sec-WebSocket-Version header. - - - -