From 8b1c5efa56cbab7cb83e4a9d1fd819dd10b3d5f0 Mon Sep 17 00:00:00 2001 From: Marek Gibek Date: Mon, 23 Jul 2012 16:34:40 +0200 Subject: [PATCH] Add new snippet: Nemerle.Async. This is an implementation of C# 5.0's compatible async/await keywords for Nemerle language. You can find more details here: https://sites.google.com/site/gibekm/programming/nemerle/asyncawait. --- .../AsyncTargetingPack-EULA.html | 116 + ...mpilerServices.AsyncTargetingPack.Net4.dll | Bin 0 -> 65696 bytes ...mpilerServices.AsyncTargetingPack.Net4.xml | 2025 +++++++++++++++++ snippets/Nemerle.Async/COPYRIGHT.txt | 29 + snippets/Nemerle.Async/HISTORY.txt | 49 + snippets/Nemerle.Async/NOTES.txt | 75 + .../Nemerle.Async.Macros/AsyncBuilderMacro.n | 406 ++++ .../Nemerle.Async.Macros/AsyncExpander.n | 531 +++++ .../Nemerle.Async.Macros.nproj | 88 + .../Properties/AssemblyInfo.n | 26 + .../Nemerle.Async.Macros/Syntax.n | 112 + snippets/Nemerle.Async/Nemerle.Async.sln | 39 + snippets/Nemerle.Async/Nemerle.Async.snk | Bin 0 -> 596 bytes .../Nemerle.Async/AsyncBuilder.n | 603 +++++ .../Nemerle.Async/Nemerle.Async/AsyncTask.n | 69 + .../Nemerle.Async/Nemerle.Async.nproj | 100 + .../Nemerle.Async/Properties/AssemblyInfo.n | 26 + snippets/Nemerle.Async/README.txt | 22 + snippets/Nemerle.Async/TODO.txt | 27 + snippets/Nemerle.Async/VERSION.txt | 1 + .../WindowsFormsTest/MainForm.Designer.n | 168 ++ .../Nemerle.Async/WindowsFormsTest/MainForm.n | 774 +++++++ .../WindowsFormsTest/MainForm.resx | 120 + .../Nemerle.Async/WindowsFormsTest/Program.n | 20 + .../Properties/AssemblyInfo.n | 35 + .../WindowsFormsTest/WindowsFormsTest.nproj | 102 + 26 files changed, 5563 insertions(+) create mode 100644 snippets/Nemerle.Async/AsyncTargetingPack.NET4/AsyncTargetingPack-EULA.html create mode 100644 snippets/Nemerle.Async/AsyncTargetingPack.NET4/Microsoft.CompilerServices.AsyncTargetingPack.Net4.dll create mode 100644 snippets/Nemerle.Async/AsyncTargetingPack.NET4/Microsoft.CompilerServices.AsyncTargetingPack.Net4.xml create mode 100644 snippets/Nemerle.Async/COPYRIGHT.txt create mode 100644 snippets/Nemerle.Async/HISTORY.txt create mode 100644 snippets/Nemerle.Async/NOTES.txt create mode 100644 snippets/Nemerle.Async/Nemerle.Async.Macros/AsyncBuilderMacro.n create mode 100644 snippets/Nemerle.Async/Nemerle.Async.Macros/AsyncExpander.n create mode 100644 snippets/Nemerle.Async/Nemerle.Async.Macros/Nemerle.Async.Macros.nproj create mode 100644 snippets/Nemerle.Async/Nemerle.Async.Macros/Properties/AssemblyInfo.n create mode 100644 snippets/Nemerle.Async/Nemerle.Async.Macros/Syntax.n create mode 100644 snippets/Nemerle.Async/Nemerle.Async.sln create mode 100644 snippets/Nemerle.Async/Nemerle.Async.snk create mode 100644 snippets/Nemerle.Async/Nemerle.Async/AsyncBuilder.n create mode 100644 snippets/Nemerle.Async/Nemerle.Async/AsyncTask.n create mode 100644 snippets/Nemerle.Async/Nemerle.Async/Nemerle.Async.nproj create mode 100644 snippets/Nemerle.Async/Nemerle.Async/Properties/AssemblyInfo.n create mode 100644 snippets/Nemerle.Async/README.txt create mode 100644 snippets/Nemerle.Async/TODO.txt create mode 100644 snippets/Nemerle.Async/VERSION.txt create mode 100644 snippets/Nemerle.Async/WindowsFormsTest/MainForm.Designer.n create mode 100644 snippets/Nemerle.Async/WindowsFormsTest/MainForm.n create mode 100644 snippets/Nemerle.Async/WindowsFormsTest/MainForm.resx create mode 100644 snippets/Nemerle.Async/WindowsFormsTest/Program.n create mode 100644 snippets/Nemerle.Async/WindowsFormsTest/Properties/AssemblyInfo.n create mode 100644 snippets/Nemerle.Async/WindowsFormsTest/WindowsFormsTest.nproj diff --git a/snippets/Nemerle.Async/AsyncTargetingPack.NET4/AsyncTargetingPack-EULA.html b/snippets/Nemerle.Async/AsyncTargetingPack.NET4/AsyncTargetingPack-EULA.html new file mode 100644 index 0000000000..7f4b08956d --- /dev/null +++ b/snippets/Nemerle.Async/AsyncTargetingPack.NET4/AsyncTargetingPack-EULA.html @@ -0,0 +1,116 @@ + + + + + Microsoft Visual Studio Async Targeting Pack: Software License Terms + + + + +

MICROSOFT SOFTWARE LICENSE TERMS

+

MICROSOFT VISUAL STUDIO ASYNC TARGETING PACK

+
+ +

These license terms are an agreement between Microsoft Corporation (or based on where you live, one of its affiliates) and you. +Please read them. They apply to the software named above, which includes the media on which you received it, if any. +The terms also apply to any Microsoft

+ +

for this software, unless other terms accompany those items. If so, those terms apply.

+ +

By using the software, you accept these terms. If you do not accept them, do not use the software.

+
+

If you comply with these license terms, you have the perpetual rights below.

+ +
    +
  1. INSTALLATION AND USE RIGHTS. One user may install and use any number of copies of the software on your + devices to design, develop and test your programs.
  2. +
  3. DISTRIBUTABLE CODE. The software is comprised of Distributable Code. + "Distributable Code" is code that you are permitted to distribute in programs you develop if you comply with the terms below. +
      +
    1. Right to Use and Distribute. +
        +
      • You may copy and distribute the object code form of the software.
      • +
      • Third Party Distribution. You may permit distributors of your programs to copy and distribute the Distributable Code as + part of those programs.
      • +
    2. +
    3. Distribution Requirements. For any Distributable Code you distribute, you must +
        +
      • add significant primary functionality to it in your programs;
      • +
      • distribute Distributable Code included in a setup program only as part of that setup program without modification;
      • +
      • require distributors and external end users to agree to terms that protect it at least as much as this agreement;
      • +
      • display your valid copyright notice on your programs; and
      • +
      • indemnify, defend, and hold harmless Microsoft from any claims, including attorneys' fees, related to the distribution or + use of your programs.
      • +
    4. +
    5. Distribution Restrictions. You may not +
        +
      • alter any copyright, trademark or patent notice in the Distributable Code;
      • +
      • use Microsoft's trademarks in your programs' names or in a way that suggests your programs come from or are endorsed by Microsoft;
      • +
      • distribute Distributable Code to run on a platform other than the Windows platform;
      • +
      • include Distributable Code in malicious, deceptive or unlawful programs; or
      • +
      • modify or distribute the source code of any Distributable Code so that any part of it becomes subject to an Excluded License. + An Excluded License is one that requires, as a condition of use, modification or distribution, that +
          +
        • the code be disclosed or distributed in source code form; or
        • +
        • others have the right to modify it.
        • +
      • +
    6. +
  4. +
  5. SCOPE OF LICENSE. The software is licensed, not sold. This agreement only gives you some rights to use the software. + Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only + as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the software that only allow you + to use it in certain ways. You may not +
      +
    • work around any technical limitations in the software;
    • +
    • reverse engineer, decompile or disassemble the software, except and only to the extent that applicable law expressly permits, + despite this limitation;
    • +
    • make more copies of the software than specified in this agreement or allowed by applicable law, despite this limitation;
    • +
    • publish the software for others to copy;
    • +
    • rent, lease or lend the software;
    • +
    • transfer the software or this agreement to any third party; or
    • +
    • use the software for commercial software hosting services.
    • +
  6. +
  7. BACKUP COPY.You may make one backup copy of the software. You may use it only to reinstall the software.
  8. +
  9. EXPORT RESTRICTIONS.The software is subject to United States export laws and regulations. You must comply with all domestic + and international export laws and regulations that apply to the software. These laws include restrictions on destinations, end users and end use. + For additional information, see www.microsoft.com/exporting.
  10. +
  11. SUPPORT SERVICES.Because this software is "as is", we may not provide support services for it.
  12. +
  13. ENTIRE AGREEMENT.This agreement, and the terms for supplements, updates, Internet-based services and support services that you + use, are the entire agreement for the software and support services.
  14. +
  15. APPLICABLE LAW. +
      +
    1. United States. If you acquired the software in the United States, Washington state law governs the interpretation of this + agreement and applies to claims for breach of it, regardless of conflict of laws principles. The laws of the state where you live govern all + other claims, including claims under state consumer protection laws, unfair competition laws, and in tort.
    2. +
    3. Outside the United States.If you acquired the software in any other country, the laws of that country apply.
    4. +
  16. +
  17. LEGAL EFFECT.This agreement describes certain legal rights. You may have other rights under the laws of your country. + You may also have rights with respect to the party from whom you acquired the software. This agreement does not change your rights under + the laws of your country if the laws of your country do not permit it to do so.
  18. +
  19. DISCLAIMER OF WARRANTY. The software is licensed "as-is". You bear the risk of using it. Microsoft gives no express warranties, + guarantees or conditions. You may have additional consumer rights or statutory guarantees under your local laws which this agreement + cannot change. To the extent permitted under your local laws, Microsoft excludes the implied warranties of merchantability, fitness for + a particular purpose and non-infringement.
    + FOR AUSTRALIA – You have statutory guarantees under the Australian Consumer Law and nothing in these terms is intended + to affect those rights.
  20. +
  21. LIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES. You can recover from Microsoft and its suppliers only direct damages up to + U.S. $5.00. You cannot recover any other damages, including consequential, lost profits, special, indirect or incidental damages.
    + This limitation applies to +
      +
    • anything related to the software, services, content (including code) on third party Internet sites, or third party programs; and
    • +
    • claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent + permitted by applicable law.
    • +
    + It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not + apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.
  22. +
+ + \ No newline at end of file diff --git a/snippets/Nemerle.Async/AsyncTargetingPack.NET4/Microsoft.CompilerServices.AsyncTargetingPack.Net4.dll b/snippets/Nemerle.Async/AsyncTargetingPack.NET4/Microsoft.CompilerServices.AsyncTargetingPack.Net4.dll new file mode 100644 index 0000000000000000000000000000000000000000..d404ff0f54746272dda600e1c0cd44890c8c7bff GIT binary patch literal 65696 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 + + + Microsoft.CompilerServices.AsyncTargetingPack.Net4 + + + + Provides extension methods for threading-related types. + Asynchronous wrappers for .NET Framework operations. + Provides extension methods for threading-related types. + AsyncCtpThreadingExtensions is a placeholder. + + + Gets an awaiter used to await this . + The task to await. + An awaiter instance. + + + Gets an awaiter used to await this . + Specifies the type of data returned by the task. + The task to await. + An awaiter instance. + + + Creates and configures an awaitable object for awaiting the specified task. + The task to be awaited. + + true to automatic marshag back to the original call site's current SynchronizationContext + or TaskScheduler; otherwise, false. + + The instance to be awaited. + + + Creates and configures an awaitable object for awaiting the specified task. + The task to be awaited. + + true to automatic marshag back to the original call site's current SynchronizationContext + or TaskScheduler; otherwise, false. + + The instance to be awaited. + + + Returns a canceled task. + The cancellation token. + The canceled task. + + + Returns a canceled task. + Specifies the type of the result. + The cancellation token. + The canceled task. + + + + Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read. + + A Task that represents the asynchronous read. + The source. + The buffer to read data into. + The byte offset in at which to begin reading. + The maximum number of bytes to read. + The array length minus is less than . + is null. + or is negative. + An asynchronous read was attempted past the end of the file. + + + + Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read. + + A Task that represents the asynchronous read. + The source. + The buffer to read data into. + The byte offset in at which to begin reading. + The maximum number of bytes to read. + The cancellation token. + The array length minus is less than . + is null. + or is negative. + An asynchronous read was attempted past the end of the file. + + + + Writes asynchronously a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written. + + A Task that represents the asynchronous write. + The source. + The buffer containing data to write to the current stream. + The zero-based byte offset in at which to begin copying bytes to the current stream. + The maximum number of bytes to write. + length minus is less than . + is null. + or is negative. + The stream does not support writing. + The stream is closed. + An I/O error occurred. + + + + Writes asynchronously a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written. + + A Task that represents the asynchronous write. + The source. + The buffer containing data to write to the current stream. + The zero-based byte offset in at which to begin copying bytes to the current stream. + The maximum number of bytes to write. + The cancellation token. + length minus is less than . + is null. + or is negative. + The stream does not support writing. + The stream is closed. + An I/O error occurred. + + + + Flushes asynchronously the current stream. + + A Task that represents the asynchronous flush. + + + + Flushes asynchronously the current stream. + + A Task that represents the asynchronous flush. + + + + Reads all the bytes from the current stream and writes them to the destination stream. + + The source stream. + The stream that will contain the contents of the current stream. + A Task that represents the asynchronous operation. + + + + Reads all the bytes from the current stream and writes them to the destination stream. + + The source stream. + The stream that will contain the contents of the current stream. + The size of the buffer. This value must be greater than zero. The default size is 4096. + A Task that represents the asynchronous operation. + + + + Reads all the bytes from the current stream and writes them to the destination stream. + + The source stream. + The stream that will contain the contents of the current stream. + The size of the buffer. This value must be greater than zero. The default size is 4096. + The cancellation token to use to cancel the asynchronous operation. + A Task that represents the asynchronous operation. + + + + Reads all the bytes from the current stream and writes them to the destination stream. + + The source stream. + The stream that will contain the contents of the current stream. + The size of the buffer. This value must be greater than zero. The default size is 4096. + The cancellation token to use to cancel the asynchronous operation. + A Task that represents the asynchronous operation. + + + + Reads a maximum of count characters from the reader asynchronously and writes + the data to buffer, beginning at index. + + + When the operation completes, contains the specified character array with the + values between index and (index + count - 1) replaced by the characters read + from the current source. + + + The maximum number of characters to read. If the end of the stream is reached + before count of characters is read into buffer, the current method returns. + + The place in buffer at which to begin writing. + the source reader. + A Task that represents the asynchronous operation. + + + + Reads asynchronously a maximum of count characters from the current stream, and writes the + data to buffer, beginning at index. + + The source reader. + + When this method returns, this parameter contains the specified character + array with the values between index and (index + count -1) replaced by the + characters read from the current source. + + The position in buffer at which to begin writing. + The maximum number of characters to read. + A Task that represents the asynchronous operation. + + + + Reads a line of characters from the reader and returns the string asynchronously. + + the source reader. + A Task that represents the asynchronous operation. + + + + Reads all characters from the current position to the end of the TextReader + and returns them as one string asynchronously. + + the source reader. + A Task that represents the asynchronous operation. + + + Writes a string asynchronously to a text stream. + The writer. + The string to write. + A Task representing the asynchronous write. + + + Writes a char asynchronously to a text stream. + The writer. + The char to write. + A Task representing the asynchronous write. + + + Writes a char array asynchronously to a text stream. + The writer. + The buffer to write. + A Task representing the asynchronous write. + + + Writes a subarray of characters asynchronously to a text stream. + The writer. + The buffer to write. + Starting index in the buffer. + The number of characters to write. + A Task representing the asynchronous write. + + + Writes a line terminator asynchronously to a text stream. + The writer. + A Task representing the asynchronous write. + + + Writes a string followed by a line terminator asynchronously to a text stream. + The writer. + The string to write. + A Task representing the asynchronous write. + + + Writes a char followed by a line terminator asynchronously to a text stream. + The writer. + The char to write. + A Task representing the asynchronous write. + + + Writes a char array followed by a line terminator asynchronously to a text stream. + The writer. + The buffer to write. + A Task representing the asynchronous write. + + + Writes a subarray of characters followed by a line terminator asynchronously to a text stream. + The writer. + The buffer to write. + Starting index in the buffer. + The number of characters to write. + A Task representing the asynchronous write. + + + + Clears all buffers for the current writer and causes any buffered data to + be written to the underlying device. + + The writer. + A Task representing the asynchronous flush. + + + Starts an asynchronous request for a web resource. + Task that represents the asynchronous request. + The stream is already in use by a previous call to . + + The source. + + + Starts an asynchronous request for a object to use to write data. + Task that represents the asynchronous request. + The property is GET and the application writes to the stream. + The stream is being used by a previous call to . + No write stream is available. + + The source. + + + + Completes the Task if the user state matches the TaskCompletionSource. + + Specifies the type of data returned by the Task. + The TaskCompletionSource. + The completion event arguments. + Whether we require the tcs to match the e.UserState. + A function that gets the result with which to complete the task. + An action used to unregister work when the operaiton completes. + + + Downloads the resource with the specified URI as a string, asynchronously. + The WebClient. + The URI from which to download data. + A Task that contains the downloaded string. + + + Downloads the resource with the specified URI as a string, asynchronously. + The WebClient. + The URI from which to download data. + A Task that contains the downloaded string. + + + Opens a readable stream for the data downloaded from a resource, asynchronously. + The WebClient. + The URI for which the stream should be opened. + A Task that contains the opened stream. + + + Opens a readable stream for the data downloaded from a resource, asynchronously. + The WebClient. + The URI for which the stream should be opened. + A Task that contains the opened stream. + + + Opens a writeable stream for uploading data to a resource, asynchronously. + The WebClient. + The URI for which the stream should be opened. + A Task that contains the opened stream. + + + Opens a writeable stream for uploading data to a resource, asynchronously. + The WebClient. + The URI for which the stream should be opened. + A Task that contains the opened stream. + + + Opens a writeable stream for uploading data to a resource, asynchronously. + The WebClient. + The URI for which the stream should be opened. + The HTTP method that should be used to open the stream. + A Task that contains the opened stream. + + + Opens a writeable stream for uploading data to a resource, asynchronously. + The WebClient. + The URI for which the stream should be opened. + The HTTP method that should be used to open the stream. + A Task that contains the opened stream. + + + Uploads data in a string to the specified resource, asynchronously. + The WebClient. + The URI to which the data should be uploaded. + The data to upload. + A Task containing the data in the response from the upload. + + + Uploads data in a string to the specified resource, asynchronously. + The WebClient. + The URI to which the data should be uploaded. + The data to upload. + A Task containing the data in the response from the upload. + + + Uploads data in a string to the specified resource, asynchronously. + The WebClient. + The URI to which the data should be uploaded. + The HTTP method that should be used to upload the data. + The data to upload. + A Task containing the data in the response from the upload. + + + Uploads data in a string to the specified resource, asynchronously. + The WebClient. + The URI to which the data should be uploaded. + The HTTP method that should be used to upload the data. + The data to upload. + A Task containing the data in the response from the upload. + + + Converts a path to a Uri using the WebClient's logic. + Based on WebClient's private GetUri method. + + + Converts a path to a Uri using the WebClient's logic. + Based on WebClient's private GetUri method. + + + Downloads the resource with the specified URI as a byte array, asynchronously. + The WebClient. + The URI from which to download data. + A Task that contains the downloaded data. + + + Downloads the resource with the specified URI as a byte array, asynchronously. + The WebClient. + The URI from which to download data. + A Task that contains the downloaded data. + + + Downloads the resource with the specified URI to a local file, asynchronously. + The WebClient. + The URI from which to download data. + The name of the local file that is to receive the data. + A Task that contains the downloaded data. + + + Downloads the resource with the specified URI to a local file, asynchronously. + The WebClient. + The URI from which to download data. + The name of the local file that is to receive the data. + A Task that contains the downloaded data. + + + Uploads data to the specified resource, asynchronously. + The WebClient. + The URI to which the data should be uploaded. + The data to upload. + A Task containing the data in the response from the upload. + + + Uploads data to the specified resource, asynchronously. + The WebClient. + The URI to which the data should be uploaded. + The data to upload. + A Task containing the data in the response from the upload. + + + Uploads data to the specified resource, asynchronously. + The WebClient. + The URI to which the data should be uploaded. + The HTTP method that should be used to upload the data. + The data to upload. + A Task containing the data in the response from the upload. + + + Uploads data to the specified resource, asynchronously. + The WebClient. + The URI to which the data should be uploaded. + The HTTP method that should be used to upload the data. + The data to upload. + A Task containing the data in the response from the upload. + + + Uploads a file to the specified resource, asynchronously. + The WebClient. + The URI to which the file should be uploaded. + A path to the file to upload. + A Task containing the data in the response from the upload. + + + Uploads a file to the specified resource, asynchronously. + The WebClient. + The URI to which the file should be uploaded. + A path to the file to upload. + A Task containing the data in the response from the upload. + + + Uploads a file to the specified resource, asynchronously. + The WebClient. + The URI to which the file should be uploaded. + The HTTP method that should be used to upload the file. + A path to the file to upload. + A Task containing the data in the response from the upload. + + + Uploads a file to the specified resource, asynchronously. + The WebClient. + The URI to which the file should be uploaded. + The HTTP method that should be used to upload the file. + A path to the file to upload. + A Task containing the data in the response from the upload. + + + Causes an online announcement (Hello) message to be sent asynchronously with the specified endpoint discovery metadata and user-defined state. The specified is called when the operation completes. + Task instance. + The endpoint discovery metadata. + The source. + + + Causes an offline announcement (Bye) message to be sent asynchronously with the specified endpoint discovery metadata and user-defined state. The specified is called when the operation completes. + Task instance. + The endpoint discovery metadata. + The source. + + + Begins asynchronously retrieving an incoming request. + Task object that indicates the status of the asynchronous operation. + A Win32 function call failed. Check the exception's property to determine the cause of the exception. + This object has not been started or is currently stopped. + This object is closed. + The source. + + + Starts an asynchronous request for the client's X.509 v.3 certificate. + Task that indicates the status of the operation. + The source. + + + Called by clients to begin an asynchronous operation to authenticate the client, and optionally the server, in a client-server connection. This method does not block. + Task object indicating the status of the asynchronous operation. + The authentication failed. You can use this object to retry the authentication. + The authentication failed. You can use this object to retry the authentication. + This object has been closed. + Authentication has already occurred.- or -This stream was used previously to attempt authentication as the server. You cannot use the stream to retry authentication as the client. + The source. + + + Called by clients to begin an asynchronous operation to authenticate the client, and optionally the server, in a client-server connection. The authentication process uses the specified credentials. This method does not block. + Task object indicating the status of the asynchronous operation. + The that is used to establish the identity of the client. + The Service Principal Name (SPN) that uniquely identifies the server to authenticate. + is null.- or - is null. + The authentication failed. You can use this object to retry the authentication. + The authentication failed. You can use this object to retry the authentication. + This object has been closed. + Authentication has already occurred.- or -This stream was used previously to attempt authentication as the server. You cannot use the stream to retry authentication as the client. + The source. + + + Called by clients to begin an asynchronous operation to authenticate the client, and optionally the server, in a client-server connection. The authentication process uses the specified credentials and channel binding. This method does not block. + Task object indicating the status of the asynchronous operation. + The that is used to establish the identity of the client. + The that is used for extended protection. + The Service Principal Name (SPN) that uniquely identifies the server to authenticate. + is null.- or - is null. + The authentication failed. You can use this object to retry the authentication. + The authentication failed. You can use this object to retry the authentication. + Authentication has already occurred.- or -This stream was used previously to attempt authentication as the server. You cannot use the stream to retry authentication as the client. + This object has been closed. + The source. + + + Called by servers to begin an asynchronous operation to authenticate the client, and optionally the server, in a client-server connection. This method does not block. + Task object indicating the status of the asynchronous operation. + The authentication failed. You can use this object to retry the authentication. + The authentication failed. You can use this object to retry the authentication. + This object has been closed. + Windows 95 and Windows 98 are not supported. + The source. + + + Called by servers to begin an asynchronous operation to authenticate the client, and optionally the server, in a client-server connection. The authentication process uses the specified extended protection policy. This method does not block. + Task object indicating the status of the asynchronous operation. + The that is used for extended protection. + The and on the extended protection policy passed in the parameter are both null. + The authentication failed. You can use this object to retry the authentication. + The authentication failed. You can use this object to retry the authentication. + Windows 95 and Windows 98 are not supported. + This object has been closed. + The source. + + + Called by servers to begin an asynchronous operation to authenticate the client, and optionally the server, in a client-server connection. The authentication process uses the specified server credentials and authentication options. This method does not block. + Task object indicating the status of the asynchronous operation. + The that is used to establish the identity of the client. + One of the values, indicating the security services for the stream. + One of the values, indicating how the server can use the client's credentials to access resources. + is null. + must be , , or , + The authentication failed. You can use this object to retry the authentication. + The authentication failed. You can use this object to retry the authentication. + This object has been closed. + Authentication has already occurred.- or -This stream was used previously to attempt authentication as the client. You cannot use the stream to retry authentication as the server. + Windows 95 and Windows 98 are not supported. + The source. + + + Called by clients to begin an asynchronous operation to authenticate the server and optionally the client. + Task object that indicates the status of the asynchronous operation. + The name of the server that shares this . + is null. + The authentication failed and left this object in an unusable state. + Authentication has already occurred.-or-Server authentication using this was tried previously.-or- Authentication is already in progress. + This object has been closed. + The source. + + + Called by servers to begin an asynchronous operation to authenticate the client and optionally the server in a client-server connection. + Task object indicating the status of the asynchronous operation. + The X509Certificate used to authenticate the server. + is null. + The authentication failed and left this object in an unusable state. + Authentication has already occurred.-or-Client authentication using this was tried previously.-or- Authentication is already in progress. + This object has been closed. + The method is not supported on Windows 95, Windows 98, or Windows Millennium. + The source. + + + Starts an asynchronous request for a remote host connection. The host is specified by a host name and a port number. + Task that represents the asynchronous connection. + The name of the remote host. + The port number of the remote host. + is null. + The has been closed. + This method is valid for sockets in the or families. + The port number is not valid. + The is ing. + + The source. + + + Starts an asynchronous request for a remote host connection. The host is specified by an and a port number. + Task that represents the asynchronous connection. + The of the remote host. + The port number of the remote host. + is null. + An error occurred when attempting to access the socket. See the Remarks section for more information. + The has been closed. + The is not in the socket family. + The port number is not valid. + The length of is zero. + The is ing. + + The source. + + + Starts an asynchronous request for a remote host connection. The host is specified by an array and a port number. + Task that represents the asynchronous connections. + At least one , designating the remote host. + The port number of the remote host. + is null. + An error occurred when attempting to access the socket. See the Remarks section for more information. + The has been closed. + This method is valid for sockets that use or . + The port number is not valid. + The length of is zero. + The is ing. + + The source. + + + Starts an asynchronous operation to accept an incoming connection attempt. + Task that represents the asynchronous creation of the . + An error occurred while attempting to access the socket. See the Remarks section for more information. + The has been closed. + + The source. + + + Starts an asynchronous operation to accept an incoming connection attempt. + Task that represents the asynchronous creation of the . + An error occurred while attempting to access the socket. See the Remarks section for more information. + The has been closed. + + The source. + + + Sends a datagram to a destination asynchronously. The destination is specified by a . + Task object that represents the asynchronous send. + A array that contains the data to be sent. + The number of bytes to send. + The that represents the destination for the data. + The source. + + + Sends a datagram to a remote host asynchronously. The destination was specified previously by a call to . + Task object that represents the asynchronous send. + A array that contains the data to be sent. + The number of bytes to send. + The source. + + + Sends a datagram to a remote host asynchronously. The destination was specified previously by a call to . + Task object that represents the asynchronous send. + A array that contains the data to be sent. + The number of bytes to send. + The host name. + The host name. + The source. + + + Starts an asynchronous request to retrieve the stable unicast IP address table on the local computer. + Task that represents the asynchronous request. + This method is not implemented on the platform. This method uses the native NotifyStableUnicastIpAddressTable function that is supported on Windows Vista and later. + The call to the native NotifyStableUnicastIpAddressTable function failed. + The source. + + + Opens the connection asynchronously. + The source. + Task that represents the asynchronous request. + + + Opens the connection asynchronously. + The source. + The cancellation token. + Task that represents the asynchronous request. + + + Initiates the asynchronous execution of the Transact-SQL statement or stored procedure that is described by this , given a callback procedure and state information. + Task that can be used to poll or wait for results, or both; this value is also needed when invoking , which returns the number of affected rows. + Any error that occurred while executing the command text. + The name/value pair "Asynchronous Processing=true" was not included within the connection string defining the connection for this . + 2 + The source. + + + Initiates the asynchronous execution of the Transact-SQL statement or stored procedure that is described by this , given a callback procedure and state information. + Task that can be used to poll or wait for results, or both; this value is also needed when invoking , which returns the number of affected rows. + Any error that occurred while executing the command text. + The name/value pair "Asynchronous Processing=true" was not included within the connection string defining the connection for this . + 2 + The cancellation token. + The source. + + + Initiates the asynchronous execution of the Transact-SQL statement or stored procedure that is described by this and returns results as an object, using a callback procedure. + Task that can be used to poll, wait for results, or both; this value is also needed when the is called, which returns the results of the command as XML. + Any error that occurred while executing the command text. + The name/value pair "Asynchronous Processing=true" was not included within the connection string defining the connection for this . + 2 + The source. + + + Initiates the asynchronous execution of the Transact-SQL statement or stored procedure that is described by this and returns results as an object, using a callback procedure. + Task that can be used to poll, wait for results, or both; this value is also needed when the is called, which returns the results of the command as XML. + Any error that occurred while executing the command text. + The name/value pair "Asynchronous Processing=true" was not included within the connection string defining the connection for this . + 2 + The cancellation token. + The source. + + + Initiates the asynchronous execution of the Transact-SQL statement or stored procedure that is described by this and retrieves one or more result sets from the server, given a callback procedure and state information. + Task that can be used to poll, wait for results, or both; this value is also needed when invoking , which returns a instance which can be used to retrieve the returned rows. + Any error that occurred while executing the command text. + The name/value pair "Asynchronous Processing=true" was not included within the connection string defining the connection for this . + 2 + The source. + + + Initiates the asynchronous execution of the Transact-SQL statement or stored procedure that is described by this and retrieves one or more result sets from the server, given a callback procedure and state information. + Task that can be used to poll, wait for results, or both; this value is also needed when invoking , which returns a instance which can be used to retrieve the returned rows. + Any error that occurred while executing the command text. + The name/value pair "Asynchronous Processing=true" was not included within the connection string defining the connection for this . + 2 + The cancellation token. + The source. + + + Starts an asynchronous method call that returns a . + The metadata. + The source. + + + Starts an asynchronous method call that returns a using the specified address, callback, asynchronous state, and download mechanism. + The metadata obtained from the specified . + The address of the metadata. + The value to use when downloading the metadata. + The source. + + + Starts an asynchronous method call that returns a using the specified address, callback, and asynchronous state. + The metadata obtained from the specified . + The address of the metadata. + The source. + + + + Begins an asynchronous find operation with the specified criteria. + + The discovery client. + The criteria for finding services. + A Task that represents the asynchronous operation. + + + + Begins an asynchronous resolve operation with the specified criteria. + + The discovery client. + The criteria for matching a service endpoint. + A Task that represents the asynchronous operation. + + + + Asynchronously attempts to send an Internet Control Message Protocol (ICMP) echo message. + + The Ping. + An IPAddress that identifies the computer that is the destination for the ICMP echo message. + A task that represents the asynchronous operation. + + + + Asynchronously attempts to send an Internet Control Message Protocol (ICMP) echo message. + + The Ping. + + A String that identifies the computer that is the destination for the ICMP echo message. + The value specified for this parameter can be a host name or a string representation of an IP address. + + A task that represents the asynchronous operation. + + + + Asynchronously attempts to send an Internet Control Message Protocol (ICMP) echo message. + + The Ping. + An IPAddress that identifies the computer that is the destination for the ICMP echo message. + + An Int32 value that specifies the maximum number of milliseconds (after sending the echo message) + to wait for the ICMP echo reply message. + + A task that represents the asynchronous operation. + + + + Asynchronously attempts to send an Internet Control Message Protocol (ICMP) echo message. + + The Ping. + + A String that identifies the computer that is the destination for the ICMP echo message. + The value specified for this parameter can be a host name or a string representation of an IP address. + + + An Int32 value that specifies the maximum number of milliseconds (after sending the echo message) + to wait for the ICMP echo reply message. + + A task that represents the asynchronous operation. + + + + Asynchronously attempts to send an Internet Control Message Protocol (ICMP) echo message. + + The Ping. + An IPAddress that identifies the computer that is the destination for the ICMP echo message. + + An Int32 value that specifies the maximum number of milliseconds (after sending the echo message) + to wait for the ICMP echo reply message. + + + A Byte array that contains data to be sent with the ICMP echo message and returned + in the ICMP echo reply message. The array cannot contain more than 65,500 bytes. + + A task that represents the asynchronous operation. + + + + Asynchronously attempts to send an Internet Control Message Protocol (ICMP) echo message. + + The Ping. + + A String that identifies the computer that is the destination for the ICMP echo message. + The value specified for this parameter can be a host name or a string representation of an IP address. + + + An Int32 value that specifies the maximum number of milliseconds (after sending the echo message) + to wait for the ICMP echo reply message. + + + A Byte array that contains data to be sent with the ICMP echo message and returned + in the ICMP echo reply message. The array cannot contain more than 65,500 bytes. + + A task that represents the asynchronous operation. + + + + Asynchronously attempts to send an Internet Control Message Protocol (ICMP) echo message. + + The Ping. + An IPAddress that identifies the computer that is the destination for the ICMP echo message. + + An Int32 value that specifies the maximum number of milliseconds (after sending the echo message) + to wait for the ICMP echo reply message. + + + A Byte array that contains data to be sent with the ICMP echo message and returned + in the ICMP echo reply message. The array cannot contain more than 65,500 bytes. + + A PingOptions object used to control fragmentation and Time-to-Live values for the ICMP echo message packet. + A task that represents the asynchronous operation. + + + + Asynchronously attempts to send an Internet Control Message Protocol (ICMP) echo message. + + The Ping. + + A String that identifies the computer that is the destination for the ICMP echo message. + The value specified for this parameter can be a host name or a string representation of an IP address. + + + An Int32 value that specifies the maximum number of milliseconds (after sending the echo message) + to wait for the ICMP echo reply message. + + + A Byte array that contains data to be sent with the ICMP echo message and returned + in the ICMP echo reply message. The array cannot contain more than 65,500 bytes. + + A PingOptions object used to control fragmentation and Time-to-Live values for the ICMP echo message packet. + A task that represents the asynchronous operation. + + + The core implementation of SendTaskAsync. + The Ping. + A user-defined object stored in the resulting Task. + + A delegate that initiates the asynchronous send. + The provided TaskCompletionSource must be passed as the user-supplied state to the actual Ping.SendAsync method. + + + + + Sends an e-mail message asynchronously. + The client. + A String that contains the address information of the message sender. + A String that contains the address that the message is sent to. + A String that contains the subject line for the message. + A String that contains the message body. + A Task that represents the asynchronous send. + + + Sends an e-mail message asynchronously. + The client. + A MailMessage that contains the message to send. + A Task that represents the asynchronous send. + + + The core implementation of SendTaskAsync. + The client. + The user-supplied state. + + A delegate that initiates the asynchronous send. + The provided TaskCompletionSource must be passed as the user-supplied state to the actual SmtpClient.SendAsync method. + + + + + Cancels the after the specified duration. + The CancellationTokenSource. + The due time in milliseconds for the source to be canceled. + + + Cancels the after the specified duration. + The CancellationTokenSource. + The due time for the source to be canceled. + + + Asynchronously invokes an Action on the Dispatcher. + The Dispatcher. + The action to invoke. + A Task that represents the execution of the action. + + + Asynchronously invokes an Action on the Dispatcher. + The Dispatcher. + The function to invoke. + A Task that represents the execution of the function. + + + Provides an awaiter for awaiting a . + This type is intended for compiler use only. + + + + Represents an awaiter used to schedule continuations when an await operation completes. + + + + + Represents an operation that will schedule continuations when the operation completes. + + + + Schedules the continuation action to be invoked when the instance completes. + The action to invoke when the operation completes. + The argument is null (Nothing in Visual Basic). + + + Schedules the continuation action to be invoked when the instance completes. + The action to invoke when the operation completes. + The argument is null (Nothing in Visual Basic). + Unlike OnCompleted, UnsafeOnCompleted need not propagate ExecutionContext information. + + + The default value to use for continueOnCapturedContext. + + + Error message for GetAwaiter. + + + The task being awaited. + + + Initializes the . + The to be awaited. + + + Schedules the continuation onto the associated with this . + The action to invoke when the await operation completes. + The argument is null (Nothing in Visual Basic). + The awaiter was not properly initialized. + This method is intended for compiler user rather than use directly in code. + + + Schedules the continuation onto the associated with this . + The action to invoke when the await operation completes. + The argument is null (Nothing in Visual Basic). + The awaiter was not properly initialized. + This method is intended for compiler user rather than use directly in code. + + + Ends the await on the completed . + The awaiter was not properly initialized. + The task was not yet completed. + The task was canceled. + The task completed in a Faulted state. + + + + Fast checks for the end of an await operation to determine whether more needs to be done + prior to completing the await. + + The awaited task. + + + Handles validations on tasks that aren't successfully completed. + The awaited task. + + + Throws an exception to handle a task that completed in a state other than RanToCompletion. + + + Schedules the continuation onto the associated with this . + The awaited task. + The action to invoke when the await operation completes. + Whether to capture and marshal back to the current context. + The argument is null (Nothing in Visual Basic). + The awaiter was not properly initialized. + This method is intended for compiler user rather than use directly in code. + + + Invokes the delegate in a try/catch that will propagate the exception asynchronously on the ThreadPool. + + + + Copies the exception's stack trace so its stack trace isn't overwritten. + The exception to prepare. + + + A MethodInfo for the Exception.PrepForRemoting method. + + + An empty array to use with MethodInfo.Invoke. + + + Gets the MethodInfo for the internal PrepForRemoting method on Exception. + The MethodInfo if it could be retrieved, or else null. + + + Gets whether the task being awaited is completed. + This property is intended for compiler user rather than use directly in code. + The awaiter was not properly initialized. + + + Whether the current thread is appropriate for inlining the await continuation. + + + Provides an awaiter for awaiting a . + This type is intended for compiler use only. + + + The task being awaited. + + + Initializes the . + The to be awaited. + + + Schedules the continuation onto the associated with this . + The action to invoke when the await operation completes. + The argument is null (Nothing in Visual Basic). + The awaiter was not properly initialized. + This method is intended for compiler user rather than use directly in code. + + + Schedules the continuation onto the associated with this . + The action to invoke when the await operation completes. + The argument is null (Nothing in Visual Basic). + The awaiter was not properly initialized. + This method is intended for compiler user rather than use directly in code. + + + Ends the await on the completed . + The result of the completed . + The awaiter was not properly initialized. + The task was not yet completed. + The task was canceled. + The task completed in a Faulted state. + + + Gets whether the task being awaited is completed. + This property is intended for compiler user rather than use directly in code. + The awaiter was not properly initialized. + + + Provides an awaitable object that allows for configured awaits on . + This type is intended for compiler use only. + + + The task being awaited. + + + Initializes the . + The awaitable . + + true to attempt to marshal the continuation back to the original context captured; otherwise, false. + + + + Gets an awaiter for this awaitable. + The awaiter. + + + Provides an awaiter for a . + This type is intended for compiler use only. + + + The task being awaited. + + + Whether to attempt marshaling back to the original context. + + + Initializes the . + The to await. + + true to attempt to marshal the continuation back to the original context captured + when BeginAwait is called; otherwise, false. + + + + Schedules the continuation onto the associated with this . + The action to invoke when the await operation completes. + The argument is null (Nothing in Visual Basic). + The awaiter was not properly initialized. + This method is intended for compiler user rather than use directly in code. + + + Schedules the continuation onto the associated with this . + The action to invoke when the await operation completes. + The argument is null (Nothing in Visual Basic). + The awaiter was not properly initialized. + This method is intended for compiler user rather than use directly in code. + + + Ends the await on the completed . + The result of the completed . + The awaiter was not properly initialized. + The task was not yet completed. + The task was canceled. + The task completed in a Faulted state. + + + Gets whether the task being awaited is completed. + This property is intended for compiler user rather than use directly in code. + The awaiter was not properly initialized. + + + Provides an awaitable object that allows for configured awaits on . + This type is intended for compiler use only. + + + The underlying awaitable on whose logic this awaitable relies. + + + Initializes the . + The awaitable . + + true to attempt to marshal the continuation back to the original context captured; otherwise, false. + + + + Gets an awaiter for this awaitable. + The awaiter. + + + Provides an awaiter for a . + This type is intended for compiler use only. + + + The task being awaited. + + + Whether to attempt marshaling back to the original context. + + + Initializes the . + The awaitable . + + true to attempt to marshal the continuation back to the original context captured; otherwise, false. + + + + Schedules the continuation onto the associated with this . + The action to invoke when the await operation completes. + The argument is null (Nothing in Visual Basic). + The awaiter was not properly initialized. + This method is intended for compiler user rather than use directly in code. + + + Schedules the continuation onto the associated with this . + The action to invoke when the await operation completes. + The argument is null (Nothing in Visual Basic). + The awaiter was not properly initialized. + This method is intended for compiler user rather than use directly in code. + + + Ends the await on the completed . + The result of the completed . + The awaiter was not properly initialized. + The task was not yet completed. + The task was canceled. + The task completed in a Faulted state. + + + Gets whether the task being awaited is completed. + This property is intended for compiler user rather than use directly in code. + The awaiter was not properly initialized. + + + Identities the state machine type for this method. + + + Initializes the attribute. + The type that implements the state machine. + + + Gets the type that implements the state machine. + + + Identities the async state machine type for this method. + + + Initializes the attribute. + The type that implements the state machine. + + + Identities the iterator state machine type for this method. + + + Initializes the attribute. + The type that implements the state machine. + + + + Represents state machines generated for asynchronous methods. + This type is intended for compiler use only. + + + + Moves the state machine to its next state. + + + Configures the state machine with a heap-allocated replica. + The heap-allocated replica. + + + + Provides a builder for asynchronous methods that return void. + This type is intended for compiler use only. + + + + Represents an asynchronous method builder. + + + The synchronization context associated with this operation. + + + State related to the IAsyncStateMachine. + + + An object used by the debugger to uniquely identify this builder. Lazily initialized. + + + Temporary support for disabling crashing if tasks go unobserved. + + + Registers with UnobservedTaskException to suppress exception crashing. + + + Non-zero if PreventUnobservedTaskExceptions has already been invoked. + + + Initializes a new . + The initialized . + + + Initializes the . + The synchronizationContext associated with this operation. This may be null. + + + Initiates the builder's execution with the associated state machine. + Specifies the type of the state machine. + The state machine instance, passed by reference. + The argument was null (Nothing in Visual Basic). + + + Associates the builder with the state machine it represents. + The heap-allocated state machine object. + The argument was null (Nothing in Visual Basic). + The builder is incorrectly initialized. + + + Perform any initialization necessary prior to lifting the builder to the heap. + + + + Schedules the specified state machine to be pushed forward when the specified awaiter completes. + + Specifies the type of the awaiter. + Specifies the type of the state machine. + The awaiter. + The state machine. + + + + Schedules the specified state machine to be pushed forward when the specified awaiter completes. + + Specifies the type of the awaiter. + Specifies the type of the state machine. + The awaiter. + The state machine. + + + Completes the method builder successfully. + + + Faults the method builder with an exception. + The exception that is the cause of this fault. + The argument is null (Nothing in Visual Basic). + The builder is not initialized. + + + Notifies the current synchronization context that the operation completed. + + + + Gets an object that may be used to uniquely identify this builder to the debugger. + + + This property lazily instantiates the ID in a non-thread-safe manner. + It must only be used by the debugger and only in a single-threaded manner. + + + + + Provides a builder for asynchronous methods that return . + This type is intended for compiler use only. + + + AsyncTaskMethodBuilder is a value type, and thus it is copied by value. + Prior to being copied, one of its Task, SetResult, or SetException members must be accessed, + or else the copies may end up building distinct Task instances. + + + + A cached VoidTaskResult task used for builders that complete synchronously. + + + The generic builder object to which this non-generic instance delegates. + + + Initializes a new . + The initialized . + + + Initiates the builder's execution with the associated state machine. + Specifies the type of the state machine. + The state machine instance, passed by reference. + + + Associates the builder with the state machine it represents. + The heap-allocated state machine object. + The argument was null (Nothing in Visual Basic). + The builder is incorrectly initialized. + + + Perform any initialization necessary prior to lifting the builder to the heap. + + + + Schedules the specified state machine to be pushed forward when the specified awaiter completes. + + Specifies the type of the awaiter. + Specifies the type of the state machine. + The awaiter. + The state machine. + + + + Schedules the specified state machine to be pushed forward when the specified awaiter completes. + + Specifies the type of the awaiter. + Specifies the type of the state machine. + The awaiter. + The state machine. + + + + Completes the in the + RanToCompletion state. + + The builder is not initialized. + The task has already completed. + + + + Completes the in the + Faulted state with the specified exception. + + The to use to fault the task. + The argument is null (Nothing in Visual Basic). + The builder is not initialized. + The task has already completed. + + + + Called by the debugger to request notification when the first wait operation + (await, Wait, Result, etc.) on this builder's task completes. + + + true to enable notification; false to disable a previously set notification. + + + + Gets the for this builder. + The representing the builder's asynchronous operation. + The builder is not initialized. + + + + Gets an object that may be used to uniquely identify this builder to the debugger. + + + This property lazily instantiates the ID in a non-thread-safe manner. + It must only be used by the debugger, and only in a single-threaded manner + when no other threads are in the middle of accessing this property or this.Task. + + + + + Provides a builder for asynchronous methods that return . + This type is intended for compiler use only. + + + AsyncTaskMethodBuilder{TResult} is a value type, and thus it is copied by value. + Prior to being copied, one of its Task, SetResult, or SetException members must be accessed, + or else the copies may end up building distinct Task instances. + + + + A cached task for default(TResult). + + + State related to the IAsyncStateMachine. + + + The lazily-initialized task completion source. + + + Temporary support for disabling crashing if tasks go unobserved. + + + Initializes a new . + The initialized . + + + Initiates the builder's execution with the associated state machine. + Specifies the type of the state machine. + The state machine instance, passed by reference. + + + Associates the builder with the state machine it represents. + The heap-allocated state machine object. + The argument was null (Nothing in Visual Basic). + The builder is incorrectly initialized. + + + Perform any initialization necessary prior to lifting the builder to the heap. + + + + Schedules the specified state machine to be pushed forward when the specified awaiter completes. + + Specifies the type of the awaiter. + Specifies the type of the state machine. + The awaiter. + The state machine. + + + + Schedules the specified state machine to be pushed forward when the specified awaiter completes. + + Specifies the type of the awaiter. + Specifies the type of the state machine. + The awaiter. + The state machine. + + + + Completes the in the + RanToCompletion state with the specified result. + + The result to use to complete the task. + The task has already completed. + + + + Completes the builder by using either the supplied completed task, or by completing + the builder's previously accessed task using default(TResult). + + A task already completed with the value default(TResult). + The task has already completed. + + + + Completes the in the + Faulted state with the specified exception. + + The to use to fault the task. + The argument is null (Nothing in Visual Basic). + The task has already completed. + + + + Called by the debugger to request notification when the first wait operation + (await, Wait, Result, etc.) on this builder's task completes. + + + true to enable notification; false to disable a previously set notification. + + + This should only be invoked from within an asynchronous method, + and only by the debugger. + + + + + Gets a task for the specified result. This will either + be a cached or new task, never null. + + The result for which we need a task. + The completed task containing the result. + + + Gets the lazily-initialized TaskCompletionSource. + + + Gets the for this builder. + The representing the builder's asynchronous operation. + + + + Gets an object that may be used to uniquely identify this builder to the debugger. + + + This property lazily instantiates the ID in a non-thread-safe manner. + It must only be used by the debugger, and only in a single-threaded manner + when no other threads are in the middle of accessing this property or this.Task. + + + + Provides a base class used to cache tasks of a specific return type. + Specifies the type of results the cached tasks return. + + + + A singleton cache for this result type. + This may be null if there are no cached tasks for this TResult. + + + + Creates a non-disposable task. + The result for the task. + The cacheable task. + + + Creates a cache. + A task cache for this result type. + + + Gets a cached task if one exists. + The result for which we want a cached task. + A cached task if one exists; otherwise, null. + + + Provides a cache for Boolean tasks. + + + A true task. + + + A false task. + + + Gets a cached task for the Boolean result. + true or false + A cached task for the Boolean result. + + + Provides a cache for zero Int32 tasks. + + + The minimum value, inclusive, for which we want a cached task. + + + The maximum value, exclusive, for which we want a cached task. + + + The cache of Task{Int32}. + + + Creates an array of cached tasks for the values in the range [INCLUSIVE_MIN,EXCLUSIVE_MAX). + + + Gets a cached task for the zero Int32 result. + The integer value + A cached task for the Int32 result or null if not cached. + + + Holds state related to the builder's IAsyncStateMachine. + This is a mutable struct. Be very delicate with it. + + + A reference to the heap-allocated state machine object associated with this builder. + + + Initiates the builder's execution with the associated state machine. + Specifies the type of the state machine. + The state machine instance, passed by reference. + The argument is null (Nothing in Visual Basic). + + + Associates the builder with the state machine it represents. + The heap-allocated state machine object. + The argument was null (Nothing in Visual Basic). + The builder is incorrectly initialized. + + + + Gets the Action to use with an awaiter's OnCompleted or UnsafeOnCompleted method. + On first invocation, the supplied state machine will be boxed. + + Specifies the type of the method builder used. + Specifies the type of the state machine used. + The builder. + The state machine. + An Action to provide to the awaiter. + + + Throws the exception on the ThreadPool. + The exception to propagate. + The target context on which to propagate the exception. Null to use the ThreadPool. + + + Provides the ability to invoke a state machine's MoveNext method under a supplied ExecutionContext. + + + The context with which to run MoveNext. + + + The state machine whose MoveNext method should be invoked. + + + Initializes the runner. + The context with which to run MoveNext. + + + Invokes MoveNext under the provided context. + + + Cached delegate used with ExecutionContext.Run. + + + Invokes the MoveNext method on the supplied IAsyncStateMachine. + The IAsyncStateMachine machine instance. + + + Used with Task(of void) + + + Asynchronous wrappers for .NET Framework operations. + + + Asynchronously returns the Internet Protocol (IP) addresses for the specified host. + The host name or IP address to resolve. + An array of type System.Net.IPAddress that holds the IP addresses for the host specified. + + + Asynchronously resolves an IP address to an System.Net.IPHostEntry instance. + The IP address to resolve. + An System.Net.IPHostEntry instance that contains address information about the host. + + + Asynchronously resolves an IP address to an System.Net.IPHostEntry instance. + The host name or IP address to resolve. + An System.Net.IPHostEntry instance that contains address information about the host. + + + Defines a provider for progress updates. + The type of progress update value. + + + Reports a progress update. + The value of the updated progress. + + + Event handler for progress reports. + Specifies the type of data for the progress report. + The sender of the report. + The reported value. + + + + Provides an IProgress{T} that invokes callbacks for each reported progress value. + + Specifies the type of the progress report value. + + Any handler provided to the constructor or event handlers registered with + the event are invoked through a + instance captured + when the instance is constructed. If there is no current SynchronizationContext + at the time of construction, the callbacks will be invoked on the ThreadPool. + + + + The synchronization context captured upon construction. This will never be null. + + + The handler specified to the constructor. This may be null. + + + A cached delegate used to post invocation to the synchronization context. + + + Initializes the . + + + Initializes the with the specified callback. + + A handler to invoke for each reported progress value. This handler will be invoked + in addition to any delegates registered with the event. + + The is null (Nothing in Visual Basic). + + + Reports a progress change. + The value of the updated progress. + + + Reports a progress change. + The value of the updated progress. + + + Invokes the action and event callbacks. + The progress value. + + + Raised for each reported progress value. + + Handlers registered with this event will be invoked on the + captured when the instance was constructed. + + + + Holds static values for . + This avoids one static instance per type T. + + + A default synchronization context that targets the ThreadPool. + + + Provides methods for creating and manipulating tasks. + TaskEx is a placeholder. + + + Creates a task that runs the specified action. + The action to execute asynchronously. + A task that represents the completion of the action. + The argument is null. + + + Creates a task that runs the specified action. + The action to execute. + The CancellationToken to use to request cancellation of this task. + A task that represents the completion of the action. + The argument is null. + + + Creates a task that runs the specified function. + The function to execute asynchronously. + A task that represents the completion of the action. + The argument is null. + + + Creates a task that runs the specified function. + The action to execute. + The CancellationToken to use to cancel the task. + A task that represents the completion of the action. + The argument is null. + + + Creates a task that runs the specified function. + The action to execute asynchronously. + A task that represents the completion of the action. + The argument is null. + + + Creates a task that runs the specified function. + The function to execute. + The CancellationToken to use to request cancellation of this task. + A task that represents the completion of the function. + The argument is null. + + + Creates a task that runs the specified function. + The function to execute asynchronously. + A task that represents the completion of the action. + The argument is null. + + + Creates a task that runs the specified function. + The action to execute. + The CancellationToken to use to cancel the task. + A task that represents the completion of the action. + The argument is null. + + + Starts a Task that will complete after the specified due time. + The delay in milliseconds before the returned task completes. + The timed Task. + + The argument must be non-negative or -1 and less than or equal to Int32.MaxValue. + + + + Starts a Task that will complete after the specified due time. + The delay before the returned task completes. + The timed Task. + + The argument must be non-negative or -1 and less than or equal to Int32.MaxValue. + + + + Starts a Task that will complete after the specified due time. + The delay before the returned task completes. + A CancellationToken that may be used to cancel the task before the due time occurs. + The timed Task. + + The argument must be non-negative or -1 and less than or equal to Int32.MaxValue. + + + + Starts a Task that will complete after the specified due time. + The delay in milliseconds before the returned task completes. + A CancellationToken that may be used to cancel the task before the due time occurs. + The timed Task. + + The argument must be non-negative or -1 and less than or equal to Int32.MaxValue. + + + + An already completed task. + + + An already canceled task. + + + Creates a Task that will complete only when all of the provided collection of Tasks has completed. + The Tasks to monitor for completion. + A Task that represents the completion of all of the provided tasks. + + If any of the provided Tasks faults, the returned Task will also fault, and its Exception will contain information + about all of the faulted tasks. If no Tasks fault but one or more Tasks is canceled, the returned + Task will also be canceled. + + The argument is null. + The argument contains a null reference. + + + Creates a Task that will complete only when all of the provided collection of Tasks has completed. + The Tasks to monitor for completion. + A Task that represents the completion of all of the provided tasks. + + If any of the provided Tasks faults, the returned Task will also fault, and its Exception will contain information + about all of the faulted tasks. If no Tasks fault but one or more Tasks is canceled, the returned + Task will also be canceled. + + The argument is null. + The argument contains a null reference. + + + Creates a Task that will complete only when all of the provided collection of Tasks has completed. + The Tasks to monitor for completion. + A Task that represents the completion of all of the provided tasks. + + If any of the provided Tasks faults, the returned Task will also fault, and its Exception will contain information + about all of the faulted tasks. If no Tasks fault but one or more Tasks is canceled, the returned + Task will also be canceled. + + The argument is null. + The argument contains a null reference. + + + Creates a Task that will complete only when all of the provided collection of Tasks has completed. + The Tasks to monitor for completion. + A Task that represents the completion of all of the provided tasks. + + If any of the provided Tasks faults, the returned Task will also fault, and its Exception will contain information + about all of the faulted tasks. If no Tasks fault but one or more Tasks is canceled, the returned + Task will also be canceled. + + The argument is null. + The argument contains a null reference. + + + Creates a Task that will complete only when all of the provided collection of Tasks has completed. + The Tasks to monitor for completion. + + A callback invoked when all of the tasks complete successfully in the RanToCompletion state. + This callback is responsible for storing the results into the TaskCompletionSource. + + A Task that represents the completion of all of the provided tasks. + The argument is null. + The argument contains a null reference. + + + Creates a Task that will complete when any of the tasks in the provided collection completes. + The Tasks to be monitored. + + A Task that represents the completion of any of the provided Tasks. The completed Task is this Task's result. + + Any Tasks that fault will need to have their exceptions observed elsewhere. + The argument is null. + The argument contains a null reference. + + + Creates a Task that will complete when any of the tasks in the provided collection completes. + The Tasks to be monitored. + + A Task that represents the completion of any of the provided Tasks. The completed Task is this Task's result. + + Any Tasks that fault will need to have their exceptions observed elsewhere. + The argument is null. + The argument contains a null reference. + + + Creates a Task that will complete when any of the tasks in the provided collection completes. + The Tasks to be monitored. + + A Task that represents the completion of any of the provided Tasks. The completed Task is this Task's result. + + Any Tasks that fault will need to have their exceptions observed elsewhere. + The argument is null. + The argument contains a null reference. + + + Creates a Task that will complete when any of the tasks in the provided collection completes. + The Tasks to be monitored. + + A Task that represents the completion of any of the provided Tasks. The completed Task is this Task's result. + + Any Tasks that fault will need to have their exceptions observed elsewhere. + The argument is null. + The argument contains a null reference. + + + Creates an already completed from the specified result. + The result from which to create the completed task. + The completed task. + + + Creates an awaitable that asynchronously yields back to the current context when awaited. + + A context that, when awaited, will asynchronously transition back into the current context. + If SynchronizationContext.Current is non-null, that is treated as the current context. + Otherwise, TaskScheduler.Current is treated as the current context. + + + + Adds the target exception to the list, initializing the list if it's null. + The list to which to add the exception and initialize if the list is null. + The exception to add, and unwrap if it's an aggregate. + + + Provides an awaitable context for switching into a target environment. + This type is intended for compiler use only. + + + Gets an awaiter for this . + An awaiter for this awaitable. + This method is intended for compiler user rather than use directly in code. + + + Provides an awaiter that switches into a target environment. + This type is intended for compiler use only. + + + A completed task. + + + Posts the back to the current context. + The action to invoke asynchronously. + The awaiter was not properly initialized. + + + Posts the back to the current context. + The action to invoke asynchronously. + The awaiter was not properly initialized. + + + Ends the await operation. + + + Gets whether a yield is not required. + This property is intended for compiler user rather than use directly in code. + + + diff --git a/snippets/Nemerle.Async/COPYRIGHT.txt b/snippets/Nemerle.Async/COPYRIGHT.txt new file mode 100644 index 0000000000..38d3ed860b --- /dev/null +++ b/snippets/Nemerle.Async/COPYRIGHT.txt @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2012 Marek Gibek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +This project is based on the Nemerle's ComputationExpressions snippet copyrighted by: +- Copyright (c) 2010 David Sorokin +- Copyright (c) 2010 rampelstinskin@gmail.com +which uses the same license. diff --git a/snippets/Nemerle.Async/HISTORY.txt b/snippets/Nemerle.Async/HISTORY.txt new file mode 100644 index 0000000000..171f9abf9d --- /dev/null +++ b/snippets/Nemerle.Async/HISTORY.txt @@ -0,0 +1,49 @@ +2012-07-22: v0.9 (150h) + +- allow using 'async' keyword as a method modifier with method returning void +- bug fixes in exception handling +- example of using CancellationToken and IProgress + +2012-07-21: v0.8 (145h) + +- syntax resembles that of C# + +2012-07-09: v0.7 (138h) + +- support for try/finally & using + +2012-07-07: v0.6 (135h) + +- support for try/catch + +2012-07-01: v0.5 (120h) + +- type inference for variables defined with await works correctly now +- type inference for for/while/do/foreach loops inside async block works correctly now + +2012-06-30: v0.4 + +- support for GetAwaiter +- support for ConfigureAwait + +2012-06-28: v0.3 + +- removed "return" keyword +- added compiler warning when async block lacks 'await' operators + +2012-06-26: v0.2 + +- replaced defcomp and callcomp keywords with one "await" +- removed support for unused ComputationExpressions keywords: + call, returncomp (optimizations for return will do the same + in the future - see TODO), yield, yieldcomp + +2012-06-25: v0.1 + +- first working version for Nemerle 1.1, .NET 4.0 and VS2010 +- based on ComputationExpressions - supports keywords: async / defcomp / callcomp +- support for Task and Task[T] +- support for while / for / foreach + +2012-06-20: beginning of the work +2012-06-16: discovered Nemerle watching videos from NDC 2012 :) diff --git a/snippets/Nemerle.Async/NOTES.txt b/snippets/Nemerle.Async/NOTES.txt new file mode 100644 index 0000000000..c2f0651ebb --- /dev/null +++ b/snippets/Nemerle.Async/NOTES.txt @@ -0,0 +1,75 @@ +Warning! This is only a rough approximation how transformed code looks like. + +Document is not precise (it was sketched before implementation, +real output code is a little bit more complicated), +but can give an idea how transformed code looks like. + +The version 1.0 of AsyncAwait uses monad approach. +It's simpler to implement in functional language like Nemerle +than state machine approach (which is used by C# compiler). + + +Source: +------- + +public async Task MethodAsync() +{ + expr1(); + + T k1 = await procAsync(); + expr2(); + + T k2 = await procAsync(); + + return k1 + k2; +} + + +Idea of what needs to be generated: +----------------------------------- + +public Task MethodAsync() +{ + TaskCompletionSource tcs = new TaskCompletionSource(); + + expr1(); + + TaskAwaiter taskAwaiter = procAsync().GetAwaiter(); + taskAwaiter.OnCompleted(() => + { + T k1 = taskAwaiter.GetResult(); + expr2(); + + taskAwaiter = procAsync().GetAwaiter(); + taskAwaiter.OnCompleted(() => + { + T k2 = taskAwaiter.GetResult(); + + tcs.SetResult(k1 + k2); + } + ); + } + ); + + return tcs.Task; +} + + +Actually generated (monad-like) code that depends on Nemerle.Async +runtime assembly to behave like the code above: +------------------------------------------------------------------ + +AsyncBuilder.Run(() => + { + expr1(); + + AsyncBuilder.Bind(procAsync(), k1 => + { + expr2(); + + AsyncBuilder.Bind(procAsync(), k2 => + { + k1 + k2; + }) + }) + }) diff --git a/snippets/Nemerle.Async/Nemerle.Async.Macros/AsyncBuilderMacro.n b/snippets/Nemerle.Async/Nemerle.Async.Macros/AsyncBuilderMacro.n new file mode 100644 index 0000000000..956e390e01 --- /dev/null +++ b/snippets/Nemerle.Async/Nemerle.Async.Macros/AsyncBuilderMacro.n @@ -0,0 +1,406 @@ +/* + * Copyright (c) 2010 rampelstinskin@gmail.com + * Copyright (c) 2012 Marek Gibek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using Nemerle; +using Nemerle.Collections; +using Nemerle.Compiler; +using Nemerle.Compiler.Parsetree; + +using System; +using System.Collections.Generic; + +namespace Nemerle.Async.Internal +{ + /// + /// This is a AsyncBuilder. + /// + public class AsyncBuilderMacro + { + public Bind(expr : PExpr, name : PExpr, cont : PExpr, + isDefine : bool, isMutable : bool) : PExpr + { + def getAwaiter = Macros.UseSiteSymbol("GetAwaiter"); + + def initName = match (name) + { + | <[ () ]> => + <[ + // needed because of validation, + // exception throwing etc. + awaiter.GetResult(); + ]>; + | _ => + if (isDefine) + { + if (isMutable) + { + <[ mutable $name = awaiter.GetResult() ]>; + } + else + { + <[ def $name = awaiter.GetResult() ]>; + } + } + else + { + <[ $name = awaiter.GetResult() ]>; + } + } + + def continuation = match (cont) + { + | <[ () ]> => <[ $initName ]> + | _ => <[ $initName; $cont ]> + } + + <[ + AsyncBuilder.Bind(() => + { + def awaiter = $expr.$(getAwaiter : name)(); + (awaiter, awaiter.IsCompleted, () => $continuation) + }) + ]> + } + + public BindAsync(expr : PExpr, name : PExpr, cont : PExpr, + isDefine : bool, isMutable : bool) : PExpr + { + def getAwaiter = Macros.UseSiteSymbol("GetAwaiter"); + + def initName = match (name) + { + | <[ () ]> => + <[ + // needed because of validation, + // exception throwing etc. + awaiter.GetResult(); + ]>; + | _ => + if (isDefine) + { + if (isMutable) + { + <[ mutable $name = awaiter.GetResult() ]>; + } + else + { + <[ def $name = awaiter.GetResult() ]>; + } + } + else + { + <[ $name = awaiter.GetResult() ]>; + } + } + + def continuation = match (cont) + { + | <[ () ]> => <[ $initName ]> + | _ => <[ $initName; $cont ]> + } + + <[ + AsyncBuilder.BindAsync(() => + { + def awaiter = $expr.$(getAwaiter : name)(); + (awaiter, awaiter.IsCompleted, () => $continuation) + }) + ]> + } + + public Combine(expr1 : PExpr, expr2 : PExpr) : PExpr + { + Bind(expr1, <[ () ]>, expr2, false, false); + } + + public CombineAsync(expr1 : PExpr, expr2 : PExpr) : PExpr + { + BindAsync(expr1, <[ () ]>, expr2, false, false); + } + + public Run(expr : PExpr) : PExpr + { + <[ AsyncBuilder.Run(() => $expr) ]> + } + + public RunAsync(expr : PExpr) : PExpr + { + <[ AsyncBuilder.RunAsync(() => $expr) ]> + } + + public While(pred : PExpr, body : PExpr) : PExpr + { + def awaiter = Macros.NewSymbol("awaiter"); + + <[ + def tcs : System.Threading.Tasks.TaskCompletionSource[object] = + System.Threading.Tasks.TaskCompletionSource(); + + def loop() : void + { + if ($pred) + { + // iteration + def $(awaiter : name) = $body.GetAwaiter(); + + // continuation + $(awaiter : name).OnCompleted(fun() : void + { + try + { + // recommended because of validation, exception throwing etc. + $(awaiter : name).GetResult(); + loop(); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + }); + } + else + { + _ = tcs.TrySetResult(null); + } + } + + try + { + loop(); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + + Nemerle.Async.Internal.AsyncTask( + tcs.Task : System.Threading.Tasks.Task); + ]> + } + + public DoWhile(pred : PExpr, body : PExpr) : PExpr + { + def awaiter = Macros.NewSymbol("awaiter"); + + <[ + def tcs : System.Threading.Tasks.TaskCompletionSource[object] = + System.Threading.Tasks.TaskCompletionSource(); + + def loop() : void + { + // iteration + def $(awaiter : name) = $body.GetAwaiter(); + + // continuation + $(awaiter : name).OnCompleted(fun () : void + { + try + { + // recommended because of validation, exception throwing etc. + $(awaiter : name).GetResult(); + + if ($pred) + { + loop() + } + else + { + _ = tcs.TrySetResult(null); + } + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + }); + } + + try + { + loop(); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + + Nemerle.Async.Internal.AsyncTask( + tcs.Task : System.Threading.Tasks.Task); + ]> + } + + protected ForEach(coll : PExpr, cont : PExpr) : PExpr + { + <[ AsyncBuilder.ForEach($coll, $cont) ]> + } + + public ForEach(name : PExpr, coll : PExpr, body : PExpr) : PExpr + { + def awaiter = Macros.NewSymbol("awaiter"); + def enumerator = Macros.NewSymbol("enumerator"); + + match (body) + { + | <[ match ($(null)) { ..$_ } ]> => + match (name) + { + | <[ $(x : name) ]> when char.IsLower(x.Id[0]) + | <[ (..$_) ]> => () + | _ => Message.FatalError("only simple names available in pattern" + " of foreach with direct matching") + } + | _ => () + } + + <[ + def tcs : System.Threading.Tasks.TaskCompletionSource[object] = + System.Threading.Tasks.TaskCompletionSource(); + + try + { + def $(enumerator : name) = $coll.GetEnumerator(); + + def loop() : void + { + if ($(enumerator : name).MoveNext()) + { + // iteration + def $name = $(enumerator : name).Current; + def $(awaiter : name) = $body.GetAwaiter(); + + // continuation + $(awaiter : name).OnCompleted(fun () : void + { + try + { + // recommended because of validation, exception throwing etc. + $(awaiter : name).GetResult(); + + loop(); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + }); + } + else + { + (($(enumerator : name) : object) :> IDisposable)?.Dispose(); + _ = tcs.TrySetResult(null); + } + } + + loop(); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + + Nemerle.Async.Internal.AsyncTask( + tcs.Task : System.Threading.Tasks.Task); + ]> + } + + public For(init : PExpr, cond : PExpr, change : PExpr, body : PExpr) : PExpr + { + def awaiter = Macros.NewSymbol("awaiter"); + + <[ + def tcs : System.Threading.Tasks.TaskCompletionSource[object] = + System.Threading.Tasks.TaskCompletionSource(); + + try + { + $init; + + def loop() : void + { + if ($cond) + { + // iteration + def $(awaiter : name) = $body.GetAwaiter(); + + // continuation + $(awaiter : name).OnCompleted(fun () : void + { + try + { + // recommended because of validation, exception throwing etc. + $(awaiter : name).GetResult(); + + $change; + loop(); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + }); + } + else + { + _ = tcs.TrySetResult(null); + } + } + + loop(); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + + Nemerle.Async.Internal.AsyncTask( + tcs.Task : System.Threading.Tasks.Task); + ]> + } + + public TryFinally(body : PExpr, handler : PExpr) : PExpr + { + <[ AsyncBuilder.TryFinally(() => $body, () => $handler) ]> + } + + protected TryCatch(body : PExpr, cont : PExpr) : PExpr + { + <[ AsyncBuilder.TryCatch(() => $body, $cont) ]> + } + + public TryCatch(body : PExpr, cases : list [TryCase]) : PExpr + { + def e = Macros.NewSymbol("e"); + def p = PExpr.Try(<[ throw $(e : name) ]>, cases); + + TryCatch(body, <[ $(e : name) => $p ]>) + } + + public Using(expr : PExpr, name : PExpr, body : PExpr) : PExpr + { + <[ AsyncBuilder.Using($expr, $name => $body) ]> + } + } +} diff --git a/snippets/Nemerle.Async/Nemerle.Async.Macros/AsyncExpander.n b/snippets/Nemerle.Async/Nemerle.Async.Macros/AsyncExpander.n new file mode 100644 index 0000000000..36dd6b7cd4 --- /dev/null +++ b/snippets/Nemerle.Async/Nemerle.Async.Macros/AsyncExpander.n @@ -0,0 +1,531 @@ +/* + * Copyright (c) 2010 David Sorokin + * Copyright (c) 2010 rampelstinskin@gmail.com + * Copyright (c) 2012 Marek Gibek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using Nemerle; +using Nemerle.Collections; +using Nemerle.Compiler; +using Nemerle.Compiler.Parsetree; + +using System; +using System.Collections.Generic; + +namespace Nemerle.Async.Internal +{ + /// + /// This module allows us to expand any async expression using + /// the specified internal builder. + /// + public module AsyncExpander + { + /// + /// Expands the expression using the specified computation builder. + /// + public Expand(builder : AsyncBuilderMacro, expr : PExpr) : PExpr + { + def transform(expr : PExpr) + { + // Returns a tuple of two values: the transformed expression and + // a flag indicating whether the former contains await expressions. + + match (expr) + { + | Sequence(exprs) => transformList(exprs); + | expr => transformList([expr]); + } + } + and transformList(exprs : list[PExpr]) + { + // Returns a tuple of two values: the result of transformation and + // a flag indicating whether the former contains await expressions. + // + // Also this is the only place where we can process the monadic binding. + + match (exprs) + { + | [] => (<[ () ]>, false) + + | expr :: exprs => + match (expr) + { + | Assign(name, MacroCall(macro_name, _, parms)) + when macro_name.Id == "await" + => + match (parms) + { + | [Expression(Assign(_, _) as ass)] => + // name = await _ = _ + Message.FatalError(ass.Location, "Assignment not allowed here"); + + | [Expression(comp)] => + // name = await comp + def (p, hasAwait) = transformList(exprs); + match (hasAwait) + { + | true => (builder.BindAsync(comp, name, p, false, false), true) + | false => (builder.Bind(comp, name, p, false, false), true) + } + + | _ => + Message.FatalError(expr.Location, "Invalid await expression."); + }; + + | Define(name, MacroCall(macro_name, _, parms)) + when macro_name.Id == "await" + => + match (parms) + { + | [Expression(Assign(_, _) as ass)] => + // def name = await _ = _ + Message.FatalError(ass.Location, "Assignment not allowed here"); + + | [Expression(comp)] => + // def name = await comp + def (p, hasAwait) = transformList(exprs); + match (hasAwait) + { + | true => (builder.BindAsync(comp, name, p, true, false), true) + | false => (builder.Bind(comp, name, p, true, false), true) + } + + | _ => + Message.FatalError(expr.Location, "Invalid await expression."); + }; + + | DefMutable(name, MacroCall(macro_name, _, parms)) + when macro_name.Id == "await" + => + match (parms) + { + | [Expression(Assign(_, _) as ass)] => + // mutable name = await _ = _ + Message.FatalError(ass.Location, "Assignment not allowed here"); + + | [Expression(comp)] => + // mutable name = await comp + def (p, hasAwait) = transformList(exprs); + match (hasAwait) + { + | true => (builder.BindAsync(comp, name, p, true, true), true) + | false => (builder.Bind(comp, name, p, true, true), true) + } + + | _ => + Message.FatalError(expr.Location, "Invalid await expression."); + }; + + | MacroCall(name, _, parms) => + match (name.Id) + { + | "await" => + match (parms) + { + | [Expression(Assign(_, _) as ass)] => + // mutable name = await _ = _ + Message.FatalError(ass.Location, "Assignment not allowed here"); + + | [Expression(comp)] => + def (p, hasAwait) = transformList(exprs); + match (hasAwait) + { + | true => (builder.BindAsync(comp, <[ () ]>, p, false, false), true) + | false => (builder.Bind(comp, <[ () ]>, p, false, false), true) + } + + | _ => + Message.FatalError(expr.Location, "Invalid await expression."); + }; + + | _ => + transformList2(expr, exprs) + } + + | expr => + transformList2(expr, exprs) + } + } + } + and transformList2(expr : PExpr, exprs : list[PExpr]) + { + // Makes the transformation a computation if required. + // Apply the monadic then function in case of need. + + match (exprs) + { + | [] => transform2(expr) + + | _ => + match (transform2(expr)) + { + | (p, true) => + def (p2, hasAwait) = transformList(exprs); + match (hasAwait) + { + | true => (builder.CombineAsync(p, p2), true) + | false => (builder.Combine(p, p2), true) + } + + | (p, false) => + def (p2, f2) = transformList(exprs); + (<[ $p; $p2 ]>, f2) + } + } + } + and transform2(expr : PExpr) + { + // This is a workhorse of the macro expander. Returns a tuple of two values: + // the result of transformation which can be either a computation (monad) or + // a simple expression and also returns a flag indicating whether this + // transformation is a computation (monad). + + match (expr) + { + | <[ def _ = _ ]> => (expr, false) + + | <[ mutable _ = _ ]> => (expr, false) + + | Match(x, cases, _) => // pattern matching + + def cs = cases.Map(fun (c) + { + def (p, f) = transform(c.body); + (MatchCase(c.patterns, p), f) + }); + + def hasAwait = cs.Exists((_, f) => f); + (PExpr.Match(x, cs.Map((c, _) => c)), hasAwait); + + | MacroCall(name, _, parms) => + match (name.Id) + { + | "if" => + match (parms) + { + | [Expression(cond), Expression(expr1), Expression(expr2)] => + def (p1, hasAwait1) = transform(expr1); + def (p2, hasAwait2) = transform(expr2); + (<[ if ($cond) $p1 else $p2 ]>, hasAwait1 | hasAwait2) + + | _ => + Message.FatalError(expr.Location, "Invalid if expression."); + }; + + | "when" => + match (parms) + { + | [Expression(cond), Expression(expr)] => + def (p, hasAwait) = transform(expr); + (<[ when ($cond) $p ]>, hasAwait) + + | _ => + Message.FatalError (expr.Location, "Invalid when expression."); + }; + + | "unless" => + match (parms) + { + | [Expression(cond), Expression(expr)] => + def (p, hasAwait) = transform(expr); + (<[ unless ($cond) $p ]>, hasAwait) + + | _ => + Message.FatalError(expr.Location, "Invalid unless expression."); + }; + + | "while" => + match (parms) + { + | [Expression(pred), Expression(body)] => + match (transform(body)) + { + | (p, false) => + (<[ while ($pred) $p ]>, false) + + | (p, true) => + (builder.While(pred, p), true) + } + + | _ => + Message.FatalError(expr.Location, "Invalid while expression."); + }; + + | "do" => + match (parms) + { + | [Expression(pred), Expression(body)] => + match (transform(body)) + { + | (p, false) => + (<[ do $p while ($pred) ]>, false) + + | (p, true) => + (builder.DoWhile(pred, p), true) + } + + | _ => + Message.FatalError(expr.Location, "Invalid do-while expression."); + }; + + | "foreach" => + match (parms) + { + | [Expression(<[ $name in $coll ]>), Expression(body)] => + match (transform(body)) + { + | (p, false) => + (<[ foreach ($name in $coll) $p ]>, false) + + | (p, true) => + (builder.ForEach(name, coll, p), true) + } + + | _ => + Message.FatalError(expr.Location, "Invalid foreach expression."); + }; + + | "for" => + match (parms) + { + | [Expression(init), Expression(cond), Expression(change), Expression(body)] => + + def init = if (init != null) init else <[ () ]>; + def cond = if (cond != null) cond else <[ true ]>; + def change = if (change != null) change else <[ () ]>; + + match (transform(body)) + { + | (p, false) => + (<[ for ($init; $cond; $change) $p ]>, false) + + | (p, true) => + (builder.For(init, cond, change, p), true) + } + + | _ => + Message.FatalError(expr.Location, "Invalid for expression."); + }; + + | "repeat" => + match (parms) + { + | [Expression(times), Expression(body)] => + + match (transform(body)) + { + | (p, false) => + (<[ repeat ($times) $p ]>, false) + + | (p, true) => + + def var = Macros.NewSymbol ("counter"); + def init = <[ mutable $(var : name) = $times ]>; + def cond = <[ $(var : name) > 0 ]>; + def change = <[ $(var : name) -- ]>; + + (builder.For(init, cond, change, p), true) + } + + | _ => + Message.FatalError(expr.Location, "Invalid repeat expression."); + }; + + | "using" => + match (parms) + { + | Expression(body) :: Expression(sec) :: tail => + + def extract (expr : SyntaxElement) + { + | Expression(body) => body + | _ => Message.FatalError (expr.Location, "Expected an expression.") + } + + match (sec) + { + | <[ match ($(null)) { ..$cases } ]> => + transformUsing(expr, body, cases, tail.Map(extract)) + | _ => + transformUsing(expr, body, [], sec :: tail.Map(extract)) + } + + | _ => + Message.FatalError(expr.Location, "Invalid using expression."); + } + + | _ => + (expr, false) + } + + | TryFinally(body, handler) => + + match (transform(body)) + { + | (p, false) => (PExpr.TryFinally(p, handler), false) + | (p, true) => (builder.TryFinally(p, handler), true) + } + + | Try (body, cases) => + transformTry(body, cases) + + | _ => + (expr, false) + } + } + and transformTry (body : PExpr, cases : list[TryCase]) + { + // Transforms the try-catch block and returns a tuple of two values: + // the result of transformation and a flag indicating whether the + // result is a computation (monad). + + def cs = cases.Map (fun (c : TryCase) + { + | Catch(exn, exn_ty, handler) => + def (p, f) = transform(handler); + (TryCase.Catch (exn, exn_ty, p), f) + + | Filter(exn, exn_ty, filter, handler) => + def (p, f) = transform(handler); + (TryCase.Filter (exn, exn_ty, filter, p), f) + + | Ellipsis(expr) => + Message.FatalError(expr.Location, "The Ellipsis construct of type TryCase is not currently supported in the computation expressions.") + }); + + def (body, hasAwait) = transform(body); + + match (hasAwait || cs.Exists((_, f) => f)) + { + | false => + (PExpr.Try(body, cs.Map ((c, _) => c)), false) + + | true => + + def ps = cs.Map(fun (c, f) + { + match (f) + { + | false => + + match (c : TryCase) + { + | Catch (exn, exn_ty, handler) => + TryCase.Catch(exn, exn_ty, handler) + + | Filter (exn, exn_ty, filter, handler) => + TryCase.Filter(exn, exn_ty, filter, handler) + + | Ellipsis (expr) => + Message.FatalError(expr.Location, "Internal error.") + } + + | true => c + } + }); + + (builder.TryCatch(body, ps), true) + } + } + and transformUsing (expr : PExpr, body : PExpr, cases : list[MatchCase], binding : list[PExpr]) + { + // Transforms the using block and returns a tuple of two values: the result of + // transformation and a flag indicating whether this result is a computation (monad). + + def (body, hasAwait) = transform(body); + + def cs = cases.Map(fun (c) + { + | <[ case: $(x : name) is $exc => $exp ]> => + def (p, f) = transform(exp); + (TryCase.Catch(Splicable.Name (x), exc, p), f) + + | <[ case: $(x : name) => $exp ]> => + def (p, f) = transform (exp); + (TryCase.Catch(Splicable.Name (x), <[ System.Exception ]>, p), f) + + | _ => + Message.FatalError("expected simple catch pattern: '| x is Exception => body'"); + }); + + def bs = binding.Map(fun (expr) + { + | <[ mutable _ = _ ]> + | DefMutable(_, _) => + + Message.FatalError(expr.Location, "A mutable reference makes no sense for " + "the using block that is converted to a computation. Use def instead or " + "declare a mutable reference outside or inside the using block.") + + | <[ def $(str : name) = $e ]> + | <[ $(str : name) = $e ]> => + (e, <[ $(str : name) ]>, false) + + | MacroCall(name, _, parms) when name.Id == "await" => + match (parms) + { + | [Expression(Assign(<[ $(str : name) ]>, e))] => (e, <[ $(str : name) ]>, true) + | _ => Message.FatalError(expr.Location, "Invalid await expression.") + } + + | e => + def x = Macros.NewSymbol(); + (e, <[ $(x : name) ]>, false) + }); + + match (hasAwait || cs.Exists((_, f) => f) || bs.Exists((_, _, f) => f)) + { + | false => (expr, false) + | true => + def body = bs.FoldRight(body, ((e, name, hasAwait), acc) => + match (hasAwait) + { + | false => builder.Using(e, name, acc) + | true => builder.Bind(e, name, builder.Using (name, name, acc), false, false) + }); + (body, true) + } + } + + def (p, hasAwait) = transform(expr); + + // --- + //Console.WriteLine ("Expansion=\r\n{0}", p); + //Console.WriteLine ("HasAwait={0}", hasAwait); + // --- + + if (!hasAwait) + { + Message.Warning("This async block lacks 'await' operators and will run synchronously. "); + Message.Hint("Consider using the 'await' operator to await non-blocking API calls, " + "or 'await Task.Run(...)' to do CPU-bound work on a background thread."); + builder.Run(p) + } + else + { + builder.RunAsync(p) + } + } + } +} diff --git a/snippets/Nemerle.Async/Nemerle.Async.Macros/Nemerle.Async.Macros.nproj b/snippets/Nemerle.Async/Nemerle.Async.Macros/Nemerle.Async.Macros.nproj new file mode 100644 index 0000000000..a9d18c8680 --- /dev/null +++ b/snippets/Nemerle.Async/Nemerle.Async.Macros/Nemerle.Async.Macros.nproj @@ -0,0 +1,88 @@ + + + + Net-4.0 + $(ProgramFiles)\Nemerle + v4.0 + true + $(NemerleBinPathRoot)\$(NemerleVersion) + Nemerle.Async.Macros + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {4FBD0FE5-66C2-4E63-A5F7-57118D75D444} + Library + Properties + Nemerle.Async + Nemerle.Async.Macros + 512 + ..\Nemerle.Async.snk + + + true + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + false + true + bin\Release\ + TRACE + prompt + 4 + $(OutputPath)\Nemerle.Async.Macros.xml + + + + + + False + $(Nemerle)\Nemerle.dll + + + False + $(Nemerle)\Nemerle.Compiler.dll + + + + + Code + + + + + Code + + + + + + + + Nemerle.Async + {c8f385de-75a2-4a06-ba0f-003febe51c6c} + True + + + + + + \ No newline at end of file diff --git a/snippets/Nemerle.Async/Nemerle.Async.Macros/Properties/AssemblyInfo.n b/snippets/Nemerle.Async/Nemerle.Async.Macros/Properties/AssemblyInfo.n new file mode 100644 index 0000000000..d149bb5417 --- /dev/null +++ b/snippets/Nemerle.Async/Nemerle.Async.Macros/Properties/AssemblyInfo.n @@ -0,0 +1,26 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Nemerle.Utility; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Nemerle.Async.Macros")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Async.Macros")] +[assembly: AssemblyCopyright("Copyright © 2012 Marek Gibek")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("5c1f6413-c03b-41af-a1bc-cdc9c534f2d5")] + +[assembly: GeneratedAssemblyVersion("$GitTag.$GitRevision.0", Defaults(GitTag="0.9", GitRevision="9999"))] diff --git a/snippets/Nemerle.Async/Nemerle.Async.Macros/Syntax.n b/snippets/Nemerle.Async/Nemerle.Async.Macros/Syntax.n new file mode 100644 index 0000000000..bc4052f4d0 --- /dev/null +++ b/snippets/Nemerle.Async/Nemerle.Async.Macros/Syntax.n @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2010 David Sorokin + * Copyright (c) 2010 rampelstinskin@gmail.com + * Copyright (c) 2012 Marek Gibek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using Nemerle; +using Nemerle.Collections; +using Nemerle.Compiler; +using Nemerle.Compiler.Parsetree; +using Nemerle.Compiler.Typedtree; + +using System; +using System.Collections.Generic; + +namespace Nemerle.Async +{ + using Async.ComputationError; + using Async.Internal; + + /// + /// Executes asynchronous block of code. + /// + public macro @async(expr) + syntax("async", expr) + { + AsyncExpander.Expand(AsyncBuilderMacro(), expr); + } + + /// + /// Creates method body for asynchronous execution. + /// + [Nemerle.MacroUsage(Nemerle.MacroPhase.BeforeTypedMembers, + Nemerle.MacroTargets.Method, + Inherited = true, + AllowMultiple = false)] + public macro AsyncMethod(typeBuilder : TypeBuilder, method : ParsedMethod) + syntax("async") + { + def returnType = typeBuilder.BindFixedType(method.header.ReturnType); + + mutable newBody = AsyncExpander.Expand(AsyncBuilderMacro(), method.Body); + + newBody = match (returnType.Hint) + { + | Some(FixedType.Void) => + // on async void method rethrow user unhandled exception (if faulted) + <[ + _ = ($(newBody) : System.Threading.Tasks.Task).ContinueWith(t => + System.Threading.ThreadPool.QueueUserWorkItem(fun (state : object) : void + { + throw state :> Exception + }, t.Exception.InnerException), + System.Threading.Tasks.TaskContinuationOptions.OnlyOnFaulted | + System.Threading.Tasks.TaskContinuationOptions.ExecuteSynchronously); + ]> + + | Some(_) => newBody + + | _ => Message.Error($"Can't determine type of $(method.header.ReturnType)"); + newBody + } + + method.Body = newBody + } + + /// + /// Awaits result of asynchronous expression. + /// + public macro @await(expr) + syntax("await", expr) + { + UnexpectedCall("await", expr) + } + + /// + /// This is a helper diagnostic module. + /// + internal module ComputationError + { + /// + /// Is is called whenever the macro specified by its name is invalid in the current context. + /// + public UnexpectedCall (name : string, expr : PExpr) : PExpr + { + Message.FatalError(expr.Location, $"Unexpected use of the $name construct. " + "It can be applied only inside the construct of the async expression or method. " + "Please refer to the documentation for more details.") + } + } +} diff --git a/snippets/Nemerle.Async/Nemerle.Async.sln b/snippets/Nemerle.Async/Nemerle.Async.sln new file mode 100644 index 0000000000..77576bd269 --- /dev/null +++ b/snippets/Nemerle.Async/Nemerle.Async.sln @@ -0,0 +1,39 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{EDCC3B85-0BAD-11DB-BC1A-00112FDE8B61}") = "Nemerle.Async", "Nemerle.Async\Nemerle.Async.nproj", "{C8F385DE-75A2-4A06-BA0F-003FEBE51C6C}" +EndProject +Project("{EDCC3B85-0BAD-11DB-BC1A-00112FDE8B61}") = "Nemerle.Async.Macros", "Nemerle.Async.Macros\Nemerle.Async.Macros.nproj", "{4FBD0FE5-66C2-4E63-A5F7-57118D75D444}" +EndProject +Project("{EDCC3B85-0BAD-11DB-BC1A-00112FDE8B61}") = "WindowsFormsTest", "WindowsFormsTest\WindowsFormsTest.nproj", "{91E23356-24C6-48ED-9D27-101D0ABADABF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AsyncTargetingPack.NET4", "AsyncTargetingPack.NET4", "{597F5F19-B0EF-4353-8BE3-FDE2052F4EA5}" + ProjectSection(SolutionItems) = preProject + AsyncTargetingPack.NET4\AsyncTargetingPack-EULA.html = AsyncTargetingPack.NET4\AsyncTargetingPack-EULA.html + AsyncTargetingPack.NET4\Microsoft.CompilerServices.AsyncTargetingPack.Net4.dll = AsyncTargetingPack.NET4\Microsoft.CompilerServices.AsyncTargetingPack.Net4.dll + AsyncTargetingPack.NET4\Microsoft.CompilerServices.AsyncTargetingPack.Net4.xml = AsyncTargetingPack.NET4\Microsoft.CompilerServices.AsyncTargetingPack.Net4.xml + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C8F385DE-75A2-4A06-BA0F-003FEBE51C6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C8F385DE-75A2-4A06-BA0F-003FEBE51C6C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C8F385DE-75A2-4A06-BA0F-003FEBE51C6C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C8F385DE-75A2-4A06-BA0F-003FEBE51C6C}.Release|Any CPU.Build.0 = Release|Any CPU + {4FBD0FE5-66C2-4E63-A5F7-57118D75D444}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4FBD0FE5-66C2-4E63-A5F7-57118D75D444}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4FBD0FE5-66C2-4E63-A5F7-57118D75D444}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4FBD0FE5-66C2-4E63-A5F7-57118D75D444}.Release|Any CPU.Build.0 = Release|Any CPU + {91E23356-24C6-48ED-9D27-101D0ABADABF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {91E23356-24C6-48ED-9D27-101D0ABADABF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {91E23356-24C6-48ED-9D27-101D0ABADABF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {91E23356-24C6-48ED-9D27-101D0ABADABF}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/snippets/Nemerle.Async/Nemerle.Async.snk b/snippets/Nemerle.Async/Nemerle.Async.snk new file mode 100644 index 0000000000000000000000000000000000000000..1146fae256af2b38800bbcd544060308019a43e0 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50097fv-S-9pPEI;e2B7k!y|MlNm(|wF9Gsn z9nVyQIS~_pUbrm~J7<^?fIh%UI%W_;8)}_~hV?J53oTHxd#ZkD-tD?kUyvMg^WQ;> zriNa{aMk~+y2S;8DdUOv&_uv{T}2th_Uly3K$A}jFd+g~?mEl1T>BPqyrbOQqt zrg2Mifj5xA1l^gENUxsmAOthXct#gbXDi@wp9&lu`wqxG^DBp;p%qz174nEale#|1 zkS&xbw0jcR%V!&T8=RL&c}#dhM?a&D${=0enR792`9=Im*SM(gJ)kJ0nopS^livSN zmprY=#v9EO68VvGh`m5Kt2o6(XxyT|^Q!n|v;i=#0X2+N2+AMKg1VrevHB`@`yx&0 zNa11(>QWv-{)R%+#srE|?qc`=A=S{yj_6~P=|=yrL+o*SV3d@+Jy1Su3c1@wdc--m zt#Kt6DCmzYQ`B{gyJB6t8Xvb0w) + /// Converts code to Task. + /// + /// This method is called when we are not returning value + /// in async {} block. + /// Example: + /// async + /// { + /// Console.WriteLine("It doesn't make much sense."); + /// } + /// + public Run(code : void -> void) : Task + { + def tcs : TaskCompletionSource[object] = TaskCompletionSource(); + + try + { + code(); + _ = tcs.TrySetResult(null); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + + tcs.Task; + } + + /// + /// Converts code to Task[A]. + /// + /// This method is called when we are returning value + /// in async {} block without calling await. + /// Example: + /// async + /// { + /// Console.WriteLine("It doesn't make much sense."); + /// 10; + /// } + /// + public Run[A](code : void -> A) : Task[A] + { + def tcs : TaskCompletionSource[A] = TaskCompletionSource(); + + try + { + _ = tcs.TrySetResult(code()); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + + tcs.Task; + } + + #endregion + + #region RunAsync + + /// + /// Starts executing async section. + /// + /// This method is called when we are not returning value implicitly + /// in async {} block (we are returning Task). + /// Example: + /// async + /// { + /// await TaskEx.Delay(5000); + /// Console.WriteLine("Async returns Task."); + /// } + /// + public RunAsync(code : void -> AsyncTask) : Task + { + try + { + code().task; + } + catch + { + ex => + def tcs : TaskCompletionSource[object] = TaskCompletionSource(); + _ = tcs.TrySetException(ex); + tcs.Task : Task; + } + } + + /// + /// Starts executing async section. + /// + /// This method is called when we are returning value explicitly + /// in async {} block (we are returning Task[T]). + /// Example: + /// async + /// { + /// await k = FuncAsync(10); + /// k + 5; + /// } + /// + public RunAsync[A](code : void -> AsyncTask[A]) : Task[A] + { + try + { + code().task; + } + catch + { + ex => + def tcs : TaskCompletionSource[A] = TaskCompletionSource(); + _ = tcs.TrySetException(ex); + tcs.Task; + } + } + + #endregion + + #region Bind + + /// + /// Adds continuation ('cont') to given task ('task'). + /// Returns async that represents continuation end. + /// Called when continuation doesn't contain awaits. + /// + /// Example: + /// await TaskEx.Delay(4000); + /// ... + /// Calls: + /// def awaiter = TaskEx.Delay(4000).GetAwaiter(); + /// Bind(awaiter, awaiter.IsCompleted, () => awaiter.GetResult, () => ...); + /// + public Bind(getAwaiter : void -> INotifyCompletion * bool * (void -> void)) : AsyncTask + { + def tcs : TaskCompletionSource[object] = TaskCompletionSource(); + + try + { + def (awaiter, _isCompleted, cont) = getAwaiter(); + + awaiter.OnCompleted(fun () : void + { + try + { + cont(); + _ = tcs.TrySetResult(null); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + }); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + + AsyncTask(tcs.Task : Task); + } + + /// + /// Adds continuation ('cont') to given task ('task'). + /// Returns async that represents continuation end. + /// Called when continuation doesn't contain awaits. + /// + /// Example: + /// await k1 = asyncFunc1(10); + /// ... + /// 10; + /// Calls: + /// def awaiter = asyncFunc1(10).GetAwaiter(); + /// Bind(awaiter, awaiter.IsCompleted, () => awaiter.GetResult, () => { def k1 = ...; 10; }); + /// + public Bind[A](getAwaiter : void -> INotifyCompletion * bool * (void -> A)) : AsyncTask[A] + { + def tcs : TaskCompletionSource[A] = TaskCompletionSource(); + + try + { + def (awaiter, _isCompleted, cont) = getAwaiter(); + + awaiter.OnCompleted(fun () : void + { + try + { + _ = tcs.TrySetResult(cont()); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + }); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + + AsyncTask(tcs.Task); + } + + #endregion + + #region BindAsync + + /// + /// Adds continuation ('cont') to given task ('task'). + /// Returns async that represents continuation end. + /// Called when continuation contains await (returns Bind(Async)). + /// + /// Example: + /// await TaskEx.Delay(4000); + /// ... + /// Calls: + /// def awaiter = TaskEx.Delay(4000).GetAwaiter(); + /// BindAsync(awaiter, awaiter.IsCompleted, () => awaiter.GetResult, () => ...); + /// + public BindAsync(getAwaiter : void -> INotifyCompletion * bool * (void -> AsyncTask)) : AsyncTask + { + def tcs : TaskCompletionSource[object] = TaskCompletionSource(); + + try + { + def (awaiter, _isCompleted, cont) = getAwaiter(); + + awaiter.OnCompleted(fun () : void + { + try + { + def taskBAwaiter = cont().GetAwaiter(); + taskBAwaiter.OnCompleted(fun () : void + { + try + { + // needed because of validation, + // exception throwing etc. + taskBAwaiter.GetResult(); + + _ = tcs.TrySetResult(null); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + }); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + }); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + + AsyncTask(tcs.Task : Task); + } + + /// + /// Adds continuation ('cont') to given task ('task'). + /// Returns async that represents continuation end. + /// Called when continuation contains await (returns Bind(Async)). + /// + /// Example: + /// await TaskEx.Delay(4000); + /// ...; + /// 10; + /// Calls: + /// def awaiter = TaskEx.Delay(4000).GetAwaiter(); + /// BindAsync(awaiter, awaiter.IsCompleted, () => awaiter.GetResult, () => { ...; 10; }); + /// + public BindAsync[A](getAwaiter : void -> INotifyCompletion * bool * (void -> AsyncTask[A])) : AsyncTask[A] + { + def tcs : TaskCompletionSource[A] = TaskCompletionSource(); + + try + { + def (awaiter, _isCompleted, cont) = getAwaiter(); + + awaiter.OnCompleted(fun () : void + { + try + { + def taskBAwaiter = cont().GetAwaiter(); + taskBAwaiter.OnCompleted(fun () : void + { + try + { + _ = tcs.TrySetResult(taskBAwaiter.GetResult()); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + }); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + }); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + + AsyncTask(tcs.Task); + } + + #endregion + + #region TryCatch + + public TryCatch[A](body : void -> AsyncTask, handler : Exception -> void) : AsyncTask + { + def tcs : TaskCompletionSource[object] = TaskCompletionSource(); + + try + { + def awaiter = body().GetAwaiter(); + awaiter.OnCompleted(fun () : void + { + try + { + // needed because of validation, + // exception throwing etc. + awaiter.GetResult(); + _ = tcs.TrySetResult(null); + } + catch + { + ex => + try + { + handler(ex); + _ = tcs.TrySetResult(null); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + } + }); + } + catch + { + ex => + try + { + handler(ex); + _ = tcs.TrySetResult(null); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + } + + AsyncTask(tcs.Task : Task); + } + + public TryCatch[A](body : void -> AsyncTask[A], handler : Exception -> A) : AsyncTask[A] + { + def tcs : TaskCompletionSource[A] = TaskCompletionSource(); + + try + { + def awaiter = body().GetAwaiter(); + awaiter.OnCompleted(fun () : void + { + try + { + _ = tcs.TrySetResult(awaiter.GetResult()); + } + catch + { + ex => + try + { + _ = tcs.TrySetResult(handler(ex)); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + } + }); + } + catch + { + ex => + try + { + _ = tcs.TrySetResult(handler(ex)); + } + catch + { + ex => _ = tcs.TrySetException(ex); + } + } + + AsyncTask(tcs.Task); + } + + #endregion + + #region TryFinally + + public TryFinally[A](body : void -> AsyncTask, handler : void -> void) : AsyncTask + { + def tcs : TaskCompletionSource[object] = TaskCompletionSource(); + + try + { + def awaiter = body().GetAwaiter(); + awaiter.OnCompleted(fun () : void + { + mutable finalException : Exception = null; + + try + { + // needed because of validation, + // exception throwing etc. + awaiter.GetResult(); + } + catch + { + ex => finalException = ex; + } + + try + { + handler(); + } + catch + { + ex => finalException = ex; + } + + // it's important to call TrySetResult or + // TrySetException after handler() executed + if (finalException == null) + { + _ = tcs.TrySetResult(null); + } + else + { + _ = tcs.TrySetException(finalException); + } + }); + } + catch + { + | ex => + mutable finalException = ex; + + try + { + handler(); + } + catch + { + ex => finalException = ex; + } + + _ = tcs.TrySetException(finalException); + } + + AsyncTask(tcs.Task : Task); + } + + public TryFinally[A](body : void -> AsyncTask[A], handler : void -> void) : AsyncTask[A] + { + def tcs : TaskCompletionSource[A] = TaskCompletionSource(); + + try + { + def awaiter = body().GetAwaiter(); + awaiter.OnCompleted(fun () : void + { + mutable finalException : Exception = null; + mutable finalResult : A; + + try + { + // needed because of validation, + // exception throwing etc. + finalResult = awaiter.GetResult(); + } + catch + { + ex => finalException = ex; + } + + try + { + handler(); + } + catch + { + ex => finalException = ex; + } + + // it's important to call TrySetResult or + // TrySetException after handler() executed + if (finalException == null) + { + _ = tcs.TrySetResult(finalResult); + } + else + { + _ = tcs.TrySetException(finalException); + } + }); + } + catch + { + | ex => + mutable finalException = ex; + + try + { + handler(); + } + catch + { + ex => finalException = ex; + } + + _ = tcs.TrySetException(finalException); + } + + AsyncTask(tcs.Task); + } + + #endregion + + #region Using + + public Using[A](resource : A, cont : A -> AsyncTask) : AsyncTask + where A : IDisposable + { + TryFinally(() => cont(resource), () => + { + def resource = resource : IDisposable; + when (resource != null) + resource.Dispose() + }) + } + + public Using[A, B](resource : A, cont : A -> AsyncTask[B]) : AsyncTask[B] + where A : IDisposable + { + TryFinally(() => cont(resource), () => + { + def resource = resource : IDisposable; + when (resource != null) + resource.Dispose() + }) + } + + #endregion + } +} diff --git a/snippets/Nemerle.Async/Nemerle.Async/AsyncTask.n b/snippets/Nemerle.Async/Nemerle.Async/AsyncTask.n new file mode 100644 index 0000000000..b00830f31c --- /dev/null +++ b/snippets/Nemerle.Async/Nemerle.Async/AsyncTask.n @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2012 Marek Gibek + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using Nemerle; +using Nemerle.Collections; +using Nemerle.Text; +using Nemerle.Utility; + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Runtime.CompilerServices; + +namespace Nemerle.Async.Internal +{ + /// + /// AsyncTask and AsyncTask[A] classes are needed for type system. + /// + /// It would be possible to replace them with Task and Task[A] + /// if Task[A] wouldn't inherit from Task. + /// But because it does, type system accepts Task and Task[A] + /// when we type "Task". Thats why AsyncTask[A] was introduced + /// which doesn't inherit from AsyncTask. + /// + [Record] + public class AsyncTask[A] + { + public task: Task[A]; + + public GetAwaiter() : TaskAwaiter[A] + { + task.GetAwaiter(); + } + } + + [Record] + public class AsyncTask + { + public task: Task; + + public GetAwaiter() : TaskAwaiter + { + task.GetAwaiter(); + } + } +} diff --git a/snippets/Nemerle.Async/Nemerle.Async/Nemerle.Async.nproj b/snippets/Nemerle.Async/Nemerle.Async/Nemerle.Async.nproj new file mode 100644 index 0000000000..de6864c36a --- /dev/null +++ b/snippets/Nemerle.Async/Nemerle.Async/Nemerle.Async.nproj @@ -0,0 +1,100 @@ + + + + Net-4.0 + $(ProgramFiles)\Nemerle + v4.0 + true + $(NemerleBinPathRoot)\$(NemerleVersion) + Nemerle.Async + + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {C8F385DE-75A2-4A06-BA0F-003FEBE51C6C} + Library + Properties + Nemerle.Async + Nemerle.Async + 512 + ..\Nemerle.Async.snk + + + true + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + false + true + bin\Release\ + TRACE + prompt + 4 + $(OutputPath)\Nemerle.Async.xml + + + + Microsoft.CompilerServices.AsyncTargetingPack.Net4 + Microsoft.CompilerServices.AsyncTargetingPack.Net4.dll + ..\AsyncTargetingPack.NET4\Microsoft.CompilerServices.AsyncTargetingPack.Net4.dll + + + + + False + $(Nemerle)\Nemerle.dll + + + System + + + + + System.Core + System.Core.dll + + + + + + Code + + + Code + + + + + + + + + + \ No newline at end of file diff --git a/snippets/Nemerle.Async/Nemerle.Async/Properties/AssemblyInfo.n b/snippets/Nemerle.Async/Nemerle.Async/Properties/AssemblyInfo.n new file mode 100644 index 0000000000..589cb07de3 --- /dev/null +++ b/snippets/Nemerle.Async/Nemerle.Async/Properties/AssemblyInfo.n @@ -0,0 +1,26 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Nemerle.Utility; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Nemerle.Async")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Nemerle.Async")] +[assembly: AssemblyCopyright("Copyright © 2012 Marek Gibek")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("d6b86cae-9687-4bcb-9c17-ebf87cdb1ba7")] + +[assembly: GeneratedAssemblyVersion("$GitTag.$GitRevision.0", Defaults(GitTag="0.9", GitRevision="9999"))] diff --git a/snippets/Nemerle.Async/README.txt b/snippets/Nemerle.Async/README.txt new file mode 100644 index 0000000000..b824cc63a8 --- /dev/null +++ b/snippets/Nemerle.Async/README.txt @@ -0,0 +1,22 @@ +This is implementation of C# 5.0's async/await keywords for Nemerle 1.1 and .NET 4.0. + +Features: +- compatible with C# 5.0 Task-based Asynchronous Pattern +- syntax resembles that of C# +- .NET 4.5 and VS2012 are not required + (works fine with .NET 4.0 and VS2010 with AsyncTargetingPack.NET4) +- support for the following language constructs: + do / while / for / foreach / try / catch / finally / using +- support for GetAwaiter +- support for ConfigureAwait +- support for IProgress +- support for CancellationToken + +Before use, please ensure that you know exactly what +"Task-based Asynchronous Pattern" is about: +http://www.microsoft.com/en-us/download/details.aspx?id=19957 + +For more info please see here: +http://sites.google.com/site/gibekm/programming/nemerle/asyncawait + +Marek Gibek diff --git a/snippets/Nemerle.Async/TODO.txt b/snippets/Nemerle.Async/TODO.txt new file mode 100644 index 0000000000..dff04b5cbd --- /dev/null +++ b/snippets/Nemerle.Async/TODO.txt @@ -0,0 +1,27 @@ +TODO: + + +for v1.0: +--------- + +- handle block statement (and maybe continue / break / return keywords + from Nemerle.Imperative namespace) + + +for v2.0: +--------- + +- generation of state machine code (more effective code, particulary try / catch / finally) + +- remove runtime dependency of "Async" library - use AsyncTaskMethodBuilder from System.Runtime.CompilerServices instead + +- optimizations, e.g: + - optimize Awaiter usage - check IsCompleted before calling OnCompleted + + - optimize tail await: "await _;" to just return "_" from async block + (something like returncomp but automatically) + +- complete implementation of scenarios using await like: + Call(await FuncAsync()) + +- tweaking code so decompilers (like ILSpy) can recognize async/await pattern diff --git a/snippets/Nemerle.Async/VERSION.txt b/snippets/Nemerle.Async/VERSION.txt new file mode 100644 index 0000000000..9fab1a3f51 --- /dev/null +++ b/snippets/Nemerle.Async/VERSION.txt @@ -0,0 +1 @@ +AsyncAwait for Nemerle - v0.9 (2012-07-22) - Marek Gibek diff --git a/snippets/Nemerle.Async/WindowsFormsTest/MainForm.Designer.n b/snippets/Nemerle.Async/WindowsFormsTest/MainForm.Designer.n new file mode 100644 index 0000000000..1d572c77f0 --- /dev/null +++ b/snippets/Nemerle.Async/WindowsFormsTest/MainForm.Designer.n @@ -0,0 +1,168 @@ +#pragma warning disable 10001 +namespace WindowsFormsTest +{ + public partial class MainForm + { + /// + /// Required designer variable. + /// + private mutable components : System.ComponentModel.IContainer = null; + + /// + /// Clean up any resources being used. + /// + /// + /// true if managed resources should be disposed; otherwise, false. + /// + protected override Dispose(disposing : bool) : void + { + when (disposing && components != null) + components.Dispose(); + + base.Dispose(disposing); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private InitializeComponent() : void + { + this._buttonTestFibonacci = System.Windows.Forms.Button(); + this.progressBar1 = System.Windows.Forms.ProgressBar(); + this.textBox1 = System.Windows.Forms.TextBox(); + this.textBox2 = System.Windows.Forms.TextBox(); + this._buttonTestGetAwaiter = System.Windows.Forms.Button(); + this._buttonTestConfigureAwait = System.Windows.Forms.Button(); + this._buttonTestTryCatch = System.Windows.Forms.Button(); + this._buttonTestTryFinally = System.Windows.Forms.Button(); + this._buttonCancel = System.Windows.Forms.Button(); + this._buttonUnhandledException = System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // _buttonTestFibonacci + // + this._buttonTestFibonacci.Location = System.Drawing.Point(13, 310); + this._buttonTestFibonacci.Margin = System.Windows.Forms.Padding(4); + this._buttonTestFibonacci.Name = "_buttonTestFibonacci"; + this._buttonTestFibonacci.Size = System.Drawing.Size(150, 28); + this._buttonTestFibonacci.TabIndex = 0; + this._buttonTestFibonacci.Text = "Test Fibonacci"; + this._buttonTestFibonacci.UseVisualStyleBackColor = true; + this._buttonTestFibonacci.Click += System.EventHandler(this.buttonTestFibonacci_Click); + // + // progressBar1 + // + this.progressBar1.Location = System.Drawing.Point(13, 273); + this.progressBar1.Margin = System.Windows.Forms.Padding(4); + this.progressBar1.Name = "progressBar1"; + this.progressBar1.Size = System.Drawing.Size(428, 29); + this.progressBar1.Style = System.Windows.Forms.ProgressBarStyle.Continuous; + this.progressBar1.TabIndex = 1; + // + // textBox1 + // + this.textBox1.Location = System.Drawing.Point(13, 13); + this.textBox1.Margin = System.Windows.Forms.Padding(4); + this.textBox1.Multiline = true; + this.textBox1.Name = "textBox1"; + this.textBox1.Size = System.Drawing.Size(250, 250); + this.textBox1.TabIndex = 2; + // + // textBox2 + // + this.textBox2.Location = System.Drawing.Point(271, 13); + this.textBox2.Margin = System.Windows.Forms.Padding(4); + this.textBox2.Multiline = true; + this.textBox2.Name = "textBox2"; + this.textBox2.Size = System.Drawing.Size(250, 250); + this.textBox2.TabIndex = 4; + // + // _buttonTestGetAwaiter + // + this._buttonTestGetAwaiter.Location = System.Drawing.Point(170, 311); + this._buttonTestGetAwaiter.Name = "_buttonTestGetAwaiter"; + this._buttonTestGetAwaiter.Size = System.Drawing.Size(150, 27); + this._buttonTestGetAwaiter.TabIndex = 5; + this._buttonTestGetAwaiter.Text = "Test GetAwaiter"; + this._buttonTestGetAwaiter.UseVisualStyleBackColor = true; + this._buttonTestGetAwaiter.Click += System.EventHandler(this.buttonTestGetAwaiter_Click); + // + // _buttonTestConfigureAwait + // + this._buttonTestConfigureAwait.Location = System.Drawing.Point(326, 312); + this._buttonTestConfigureAwait.Name = "_buttonTestConfigureAwait"; + this._buttonTestConfigureAwait.Size = System.Drawing.Size(150, 26); + this._buttonTestConfigureAwait.TabIndex = 6; + this._buttonTestConfigureAwait.Text = "Test ConfigureAwait"; + this._buttonTestConfigureAwait.UseVisualStyleBackColor = true; + this._buttonTestConfigureAwait.Click += System.EventHandler(this.buttonTestConfigureAwait_Click); + // + // _buttonTestTryCatch + // + this._buttonTestTryCatch.Location = System.Drawing.Point(13, 346); + this._buttonTestTryCatch.Name = "_buttonTestTryCatch"; + this._buttonTestTryCatch.Size = System.Drawing.Size(150, 28); + this._buttonTestTryCatch.TabIndex = 7; + this._buttonTestTryCatch.Text = "Test TryCatch"; + this._buttonTestTryCatch.UseVisualStyleBackColor = true; + this._buttonTestTryCatch.Click += System.EventHandler(this.buttonTestTryCatch_Click); + // + // _buttonTestTryFinally + // + this._buttonTestTryFinally.Location = System.Drawing.Point(170, 346); + this._buttonTestTryFinally.Name = "_buttonTestTryFinally"; + this._buttonTestTryFinally.Size = System.Drawing.Size(150, 28); + this._buttonTestTryFinally.TabIndex = 8; + this._buttonTestTryFinally.Text = "Test TryFinally"; + this._buttonTestTryFinally.UseVisualStyleBackColor = true; + this._buttonTestTryFinally.Click += System.EventHandler(this.buttonTestTryFinally_Click); + // + // _buttonCancel + // + this._buttonCancel.Enabled = false; + this._buttonCancel.Location = System.Drawing.Point(448, 273); + this._buttonCancel.Name = "_buttonCancel"; + this._buttonCancel.Size = System.Drawing.Size(73, 29); + this._buttonCancel.TabIndex = 9; + this._buttonCancel.Text = "Cancel"; + this._buttonCancel.UseVisualStyleBackColor = true; + this._buttonCancel.Click += System.EventHandler(this._buttonCancel_Click); + // + // _buttonUnhandledException + // + this._buttonUnhandledException.Location = System.Drawing.Point(326, 346); + this._buttonUnhandledException.Name = "_buttonUnhandledException"; + this._buttonUnhandledException.Size = System.Drawing.Size(150, 29); + this._buttonUnhandledException.TabIndex = 10; + this._buttonUnhandledException.Text = "Unhandled Exception"; + this._buttonUnhandledException.UseVisualStyleBackColor = true; + this._buttonUnhandledException.Click += System.EventHandler(this._buttonUnhandledException_Click); + // + // MainForm + // + this.AutoScaleDimensions = System.Drawing.SizeF(8f, 16f); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = System.Drawing.Size(532, 383); + this.Controls.Add(this._buttonUnhandledException); + this.Controls.Add(this._buttonCancel); + this.Controls.Add(this._buttonTestTryFinally); + this.Controls.Add(this._buttonTestTryCatch); + this.Controls.Add(this._buttonTestConfigureAwait); + this.Controls.Add(this._buttonTestGetAwaiter); + this.Controls.Add(this.textBox2); + this.Controls.Add(this.textBox1); + this.Controls.Add(this.progressBar1); + this.Controls.Add(this._buttonTestFibonacci); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.Margin = System.Windows.Forms.Padding(4); + this.Name = "MainForm"; + this.Text = "Nemerle Async Test Window"; + this.ResumeLayout(false); + this.PerformLayout(); + } + + private mutable progressBar1 : System.Windows.Forms.ProgressBar; + private mutable textBox1 : System.Windows.Forms.TextBox; + } +} diff --git a/snippets/Nemerle.Async/WindowsFormsTest/MainForm.n b/snippets/Nemerle.Async/WindowsFormsTest/MainForm.n new file mode 100644 index 0000000000..c326986a6c --- /dev/null +++ b/snippets/Nemerle.Async/WindowsFormsTest/MainForm.n @@ -0,0 +1,774 @@ +using Nemerle.Collections; +using Nemerle.Text; +using Nemerle.Utility; +using Nemerle.Async; +using Nemerle.Imperative; + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.Threading; +using System.Threading.Tasks; +using System.Runtime.CompilerServices; + +namespace WindowsFormsTest +{ + /// + /// MainForm. + /// + public partial class MainForm : Form + { + public this() + { + InitializeComponent(); + } + + #region Test Fibonacci + + private mutable _cancellationTokenSource : CancellationTokenSource; + + private _buttonCancel_Click (_sender : object, _e : System.EventArgs) : void + { + when (_cancellationTokenSource != null) + { + _cancellationTokenSource.Cancel(); + } + } + + private buttonTestFibonacci_Click(_sender : object, _e : System.EventArgs) : void + { + def fib(n) + { + Task.Factory.StartNew(() => + { + def fib(n) + { + if (n < 2) + 1 + else + fib(n - 2) + fib(n - 1); + } + + fib(n); + }); + } + + def proc(cur, max, cancellationToken, progress : IProgress[double]) + { + async + { + for (mutable i = cur; i <= max; i++) + { + cancellationToken.ThrowIfCancellationRequested(); + + def res = await fib(i); + + textBox1.Text = $"fib($i) = $res\r\n" + textBox1.Text; + + when (progress != null) + { + progress.Report((i * 1.0) / max); + } + } + } + } + + _ = async + { + EnableButtons(false); ClearTextboxes(); + _buttonCancel.Enabled = true; + progressBar1.Maximum = 1000; + progressBar1.Value = 0; + + _cancellationTokenSource = CancellationTokenSource(); + def time = Diagnostics.Stopwatch.StartNew(); + + try + { + await proc(1, 42, _cancellationTokenSource.Token, + Progress(fun (progress) + { + progressBar1.Value = (progress * 1000.0) :> int; + } + )); + } + catch + { + | _ is OperationCanceledException => + textBox1.Text = "Operation cancelled.\r\n" + textBox1.Text; + } + finally + { + textBox1.Text = $"$(time.Elapsed)\r\n" + textBox1.Text; + + EnableButtons(true); + _buttonCancel.Enabled = false; + } + } + } + + #endregion + + #region Test GetAwaiter + + public static GetAwaiter(this ms : int) : TaskAwaiter + { + TaskEx.Delay(ms : int).GetAwaiter(); + } + + public static GetAwaiter(this timeSpan : TimeSpan) : TaskAwaiter + { + TaskEx.Delay(timeSpan).GetAwaiter(); + } + + private async TestGetAwaiter() : Task + { + EnableButtons(false); ClearTextboxes(); + + def time = Diagnostics.Stopwatch.StartNew(); + + textBox1.Text = "New text should appear every 1 [s]\r\n"; + for (mutable i = 0; i < 4; i++) + { + await TimeSpan.FromSeconds(1); + textBox1.Text += i + "\r\n"; + } + await 1000; + + when (time.Elapsed.TotalSeconds > 4) + { + textBox1.Text += "\r\nTest passed.\r\n"; + } + + EnableButtons(true); + } + + private buttonTestGetAwaiter_Click(_sender : object, _e : System.EventArgs) : void + { + _ = TestGetAwaiter(); + } + + #endregion + + #region Test ConfigureAwait + + private buttonTestConfigureAwait_Click(_sender : object, _e : System.EventArgs) : void + { + def fib(n) + { + if (n < 2) + 1 + else + fib(n - 2) + fib(n - 1); + } + + def calc() + { + Task.Factory.StartNew(() => + { + _ = fib(35); + System.Threading.Thread.CurrentThread.ManagedThreadId + }); + } + + def calcAll(configureAwait) + { + async + { + def id1 = await calc().ConfigureAwait(configureAwait); + def id2 = System.Threading.Thread.CurrentThread.ManagedThreadId; + (id1, id2) + } + } + + def Test1() + { + async + { + textBox1.Text = "ConfigureAwait(false)\r\n\r\n"; + textBox1.Text += $"GUI thread: $(System.Threading.Thread.CurrentThread.ManagedThreadId)\r\n"; + def (id1, id2) = await calcAll(false); + textBox1.Text += $"Worker thread: $id1\r\n"; + textBox1.Text += $"Continuation thread: $id2\r\n"; + textBox1.Text += $"GUI thread: $(System.Threading.Thread.CurrentThread.ManagedThreadId)\r\n"; + when (id1 == id2) + { + textBox1.Text += "\r\nTest passed.\r\n"; + } + } + } + + def Test2() + { + async + { + textBox2.Text = "ConfigureAwait(true)\r\n\r\n"; + def id0 = System.Threading.Thread.CurrentThread.ManagedThreadId; + textBox2.Text += $"GUI thread: $id0\r\n"; + def (id1, id2) = await calcAll(true); + textBox2.Text += $"Worker thread: $id1\r\n"; + textBox2.Text += $"Continuation thread: $id2\r\n"; + textBox2.Text += $"GUI thread: $(System.Threading.Thread.CurrentThread.ManagedThreadId)\r\n"; + when (id2 == id0) + { + textBox2.Text += "\r\nTest passed.\r\n"; + } + } + } + + _ = async + { + EnableButtons(false); ClearTextboxes(); + + await Task.WhenAll(Test1(), Test2()); + + EnableButtons(true); + } + } + + #endregion + + #region Test TryCatch + + private async buttonTestTryCatch_Click(_sender : object, _e : System.EventArgs) : void + { + ClearTextboxes(); + + // Test 1 - task without try/catch results in AggregatedException + // + // async without try/catch and with Exception (ex) thrown inside + // always return Task with State = Faulted and + // Exception = AggregatedException with InnerException = ex + def task1 = async + { + throw Exception("Exception 1"); + } + + if (task1.Status == TaskStatus.Faulted && + task1.Exception != null && + task1.Exception.GetType() == typeof(AggregateException) && + task1.Exception.InnerException != null && + task1.Exception.InnerException.Message == "Exception 1") + { + textBox1.Text += "Exception test 1 passed.\r\n"; + } + else + { + textBox1.Text += "Exception test 1 failed!\r\n"; + } + + // Test 2 - exception before await + _ = async + { + try + { + throw Exception("Exception 2"); + await TaskEx.Delay(0); + } + catch + { + | ex => + if (ex.Message == "Exception 2") + { + textBox1.Text += "Exception test 2 passed.\r\n"; + } + else + { + textBox1.Text += "Exception test 2 failed!\r\n"; + } + } + } + + // Test 3 - exception after await + _ = async + { + try + { + await TaskEx.Delay(0); + throw Exception("Exception 3"); + } + catch + { + | ex => + if (ex.Message == "Exception 3") + { + textBox1.Text += "Exception test 3 passed.\r\n"; + } + else + { + textBox1.Text += "Exception test 3 failed!\r\n"; + } + } + } + + // Test 4 - exception between await and awaiter construction + _ = async + { + try + { + await TaskEx.Delay(0); + await (fun() : Task + { + throw Exception("Exception 4"); + })(); + } + catch + { + | ex => + if (ex.Message == "Exception 4") + { + textBox1.Text += "Exception test 4 passed.\r\n"; + } + else + { + textBox1.Text += "Exception test 4 failed!\r\n"; + } + } + } + + // Test 5 - double try/catch (re-throw test) + _ = async + { + try + { + try + { + await TaskEx.Delay(0); + throw Exception("Exception 5"); + } + catch + { + | ex => + throw ex; + } + } + catch + { + | ex => + if (ex.Message == "Exception 5") + { + textBox1.Text += "Exception test 5 passed.\r\n"; + } + else + { + textBox1.Text += "Exception test 5 failed!\r\n"; + } + } + } + + // Test 6 - async with return value + _ = async + { + def res = await async + { + try + { + def i = await async + { + await TaskEx.Delay(0); + 10; + } + throw Exception("Exception 6"); + i; + } + catch + { + | _ => 42; + } + } + + if (res == 42) + { + textBox1.Text += "Exception test 6 passed.\r\n"; + } + else + { + textBox1.Text += "Exception test 6 failed!\r\n"; + } + } + + // Test + // This should not throw an exception outside + _ = async + { + throw Exception("Exception A1"); + } + + // Test + // This should not throw exception outside + _ = async + { + await TaskEx.Delay(0); + throw Exception("Exception A2"); + } + } + + #endregion + + #region Test TryFinally + + private buttonTestTryFinally_Click(_sender : object, _e : System.EventArgs) : void + { + ClearTextboxes(); + + _ = async + { + try + { + await TaskEx.Delay(0); + textBox1.Text = "Before finally.\r\n"; + } + finally + { + textBox1.Text += "Finally executed.\r\n"; + } + textBox1.Text += "After finally.\r\n"; + } + } + + #endregion + + #region Test Unhandled Exception + + private async _buttonUnhandledException_Click(_sender : object, _e : System.EventArgs) : void + { + await TaskEx.Delay(100); + throw Exception("Unhandled async void exception!"); + } + + #endregion + + #region Sample constucts that should compile + + // below are few examples how we can use Async library + // they all should compile (though some with purposeful warnings) + + private P1Async(a : int, b : int) : Task[int] + { + Task.Factory.StartNew(() => + { + mutable k = 0; + for (mutable i = 0; i < 10000; i++) + for (mutable j = 0; j < 10000; j++) + { + unchecked + { + k = k + a + b; + } + } + k; + }); + } + + private AsyncConstructions() : void + { + // type of expression: Task + // warning should appear that async block lacks 'await' operators + _ = async + { + System.Diagnostics.Debug.WriteLine("It makes no sense."); + } + + // type of expression: Task + // warning should appear that async block lacks 'await' operators + _ = async + { + 42; + } + + // type of expression: Task + _ = async + { + await TaskEx.Delay(5000); + } + + // type of expression: Task + _ = async + { + await TaskEx.Delay(5000); + System.Diagnostics.Debug.WriteLine("Expression."); + } + + // type of expression: Task + _ = async + { + textBox1.Text = "aaa"; + await TaskEx.Delay(5000); + } + + // type of expression: Task + _ = async + { + textBox1.Text = "aaa"; + await TaskEx.Delay(5000); + textBox1.Text = "bbb"; + } + + // type of expression: Task[int] + _ = async + { + textBox1.Text = "aaa"; + await TaskEx.Delay(5000); + 42; + } + + // type of expression: Task + _ = async + { + textBox1.Text = "aaa"; + await TaskEx.Delay(5000); + textBox1.Text = "bbb"; + await TaskEx.Delay(5000); + } + + // type of expression: Task[int] + _ = async + { + def k1 = await P1Async(1, 12); + k1; + } + + // type of expression: Task[int] + _ = async + { + def k1 = await P1Async(1, 12); + textBox1.Text = "k1 = " + k1; + } + + // type of expression: Task[int] + // here we are returning value from P1Async method + _ = async + { + await P1Async(1, 12); + } + + // type of expression: Task[int] + // here we are ignoring return value from P1Async method + // warning should appear + _ = async + { + await P1Async(1, 12); + 42; + } + + // type of expression: Task[int] + // here we are returning return value from second P1Async method + _ = async + { + _ = await P1Async(1, 12); + await P1Async(1, 12); + } + + // type of expression: Task + // here we are ignoring return value from P1Async method + _ = async + { + _ = await P1Async(1, 12); + _ = await P1Async(1, 12); + } + + // type of expression: Task[int] + // here we are ignoring return value from P1Async method + _ = async + { + _ = await P1Async(1, 12); + _ = await P1Async(1, 12); + 42; + } + + // type of expression: Task[int] + _ = async + { + await TaskEx.Delay(3000); + def k1 = await P1Async(1, 12); + k1; + } + + // type of expression: Task[int] + _ = async + { + def k1 = await P1Async(1, 12); + await TaskEx.Delay(3000); + k1; + } + + // type of expression: Task[int] + _ = async + { + def k1 = await P1Async(1, 12); + def k2 = await P1Async(1, 23); + def k = k1 + k2; + k; + } + + // type of expression: Task + _ = async + { + def k1 = await P1Async(1, 12); + textBox1.Text = "k = " + k1; + } + + // type of expression: Task + _ = async + { + _ = await P1Async(1, 12); + await TaskEx.Delay(3000); + } + + // type of expression: Task[int] + _ = async + { + textBox1.Text = "ok"; + mutable i = 0; + while (i < 4) + { + await TaskEx.Delay(1000); + textBox1.Text = "ok " + i; + i++; + } + 42; + } + + // type of expression: Task + _ = async + { + textBox1.Text = "ok"; + def list = [1, 2, 3, 4]; + foreach (i in list) + { + await TaskEx.Delay(1000); + textBox1.Text = "ok " + i; + } + } + + // type of expression: Task + _ = async + { + textBox1.Text = "ok"; + def l = System.Collections.ArrayList(); + _ = l.Add(1); + _ = l.Add("2"); + foreach (i in l) + { + await TaskEx.Delay(1000); + textBox1.Text = "ok " + i; + } + } + + // type of expression: Task[int] + _ = async + { + mutable k = 0; + for (mutable i = 0; i < 100; i++) + { + def k1 = await P1Async(1, 12); + def _ = "i = " + i + "k1 = " + k1; + } + k; + } + + // type of expression: Task + _ = async + { + mutable i = 0; + while (i > 0) + { + def k1 = await P1Async(1, 12); + def _ = "i = " + i + "k1 = " + k1; + } + } + + // type of expression: Task + _ = async + { + mutable i = 0; + do + { + def k1 = await P1Async(1, 12); + def _ = "i = " + i + "k1 = " + k1; + } + while (i > 0) + } + + // type of expression: Task[int] + _ = async + { + textBox1.Text = "aaa"; + def k1 = await P1Async(1, 12); + textBox1.Text = "bbb"; + + //def a = await TaskEx.Delay(5000); + await TaskEx.Delay(3000); + textBox1.Text = "ccc"; + await TaskEx.Delay(3000); + + def k2 = await P1Async(1, 23); + textBox1.Text = "k1 + k2 = " + (k1 + k2); + + k1 + k2; + } + + _ = async + { + using (reader1 = StreamReader(""), + reader2 = StreamReader("")) + { + _ = reader1.ReadLine(); + _ = reader2.ReadLine(); + await TaskEx.Delay(0); + } + } + + /*_ = async + { + testblock: { + def k = 0; + testblock(4); + await TaskEx.Delay(0); + 5; + } + }*/ + } + + #endregion + + #region Private Methods + + private EnableButtons(enable : bool) : void + { + _buttonTestFibonacci.Enabled = enable; + _buttonTestGetAwaiter.Enabled = enable; + _buttonTestConfigureAwait.Enabled = enable; + _buttonTestTryCatch.Enabled = enable; + _buttonTestTryFinally.Enabled = enable; + _buttonUnhandledException.Enabled = enable; + } + + private ClearTextboxes() : void + { + textBox1.Clear(); + textBox2.Clear(); + } + + #endregion + + #region Private Members + + private mutable textBox2 : System.Windows.Forms.TextBox; + private mutable _buttonTestFibonacci : System.Windows.Forms.Button; + private mutable _buttonTestGetAwaiter : System.Windows.Forms.Button; + private mutable _buttonTestConfigureAwait : System.Windows.Forms.Button; + private mutable _buttonTestTryCatch : System.Windows.Forms.Button; + private mutable _buttonTestTryFinally : System.Windows.Forms.Button; + private mutable _buttonUnhandledException : System.Windows.Forms.Button; + private mutable _buttonCancel : System.Windows.Forms.Button; + + #endregion + } +} diff --git a/snippets/Nemerle.Async/WindowsFormsTest/MainForm.resx b/snippets/Nemerle.Async/WindowsFormsTest/MainForm.resx new file mode 100644 index 0000000000..d58980a38d --- /dev/null +++ b/snippets/Nemerle.Async/WindowsFormsTest/MainForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/snippets/Nemerle.Async/WindowsFormsTest/Program.n b/snippets/Nemerle.Async/WindowsFormsTest/Program.n new file mode 100644 index 0000000000..72a6fa0c46 --- /dev/null +++ b/snippets/Nemerle.Async/WindowsFormsTest/Program.n @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; + +namespace WindowsFormsTest +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static Main() : void + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(MainForm()); + } + } +} diff --git a/snippets/Nemerle.Async/WindowsFormsTest/Properties/AssemblyInfo.n b/snippets/Nemerle.Async/WindowsFormsTest/Properties/AssemblyInfo.n new file mode 100644 index 0000000000..25b708704a --- /dev/null +++ b/snippets/Nemerle.Async/WindowsFormsTest/Properties/AssemblyInfo.n @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: Nemerle.Macro.Resource("Resources.resx")] + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("WindowsFormsTest")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("WindowsFormsTest")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2010")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("a4f90b9c-9c96-4f45-98cc-c4f4879e1661")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/snippets/Nemerle.Async/WindowsFormsTest/WindowsFormsTest.nproj b/snippets/Nemerle.Async/WindowsFormsTest/WindowsFormsTest.nproj new file mode 100644 index 0000000000..0f55ab201f --- /dev/null +++ b/snippets/Nemerle.Async/WindowsFormsTest/WindowsFormsTest.nproj @@ -0,0 +1,102 @@ + + + + Net-4.0 + $(ProgramFiles)\Nemerle + true + $(NemerleBinPathRoot)\$(NemerleVersion) + WindowsFormsTest + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {91E23356-24C6-48ED-9D27-101D0ABADABF} + WinExe + Properties + WindowsFormsTest + WindowsFormsTest + v4.0 + 512 + + + true + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + false + true + bin\Release\ + TRACE + prompt + 4 + $(OutputPath)\$(MSBuildProjectName).xml + + + + Microsoft.CompilerServices.AsyncTargetingPack.Net4 + Microsoft.CompilerServices.AsyncTargetingPack.Net4.dll + ..\AsyncTargetingPack.NET4\Microsoft.CompilerServices.AsyncTargetingPack.Net4.dll + + + + + + + + + + + + + False + $(Nemerle)\Nemerle.dll + + + + + Form + + + MainForm.n + + + + + + + + + + MainForm.n + + + + + Nemerle.Async.Macros + {4fbd0fe5-66c2-4e63-a5f7-57118d75d444} + False + + + + + Nemerle.Async + {c8f385de-75a2-4a06-ba0f-003febe51c6c} + True + + + + + \ No newline at end of file