What is asynchronous programming???
21 replies to this topic
#1
Posted 28 April 2011 - 10:21 AM
|
|
|
#2
Posted 28 April 2011 - 10:23 AM
It's where your program requests some data but doesn't wait for the result. When the result is ready, a special 'callback' method is called to provide the data (or to signal that the data is ready). You generally use it on things that might take a while to get the result but you don't want to effectively pause your program while the results are generated and returned.
#3
Posted 28 April 2011 - 10:25 AM
will it be problem for you to put some code with example and comments where exactlly is that inside code
#4
Posted 02 May 2011 - 02:26 PM
ok...next question...can asynchronous programming be for anything else except avoiding blocking user interface???
#5
Posted 03 May 2011 - 12:51 PM
any tutorials for asynchronous programming in c#???
#6
Posted 04 May 2011 - 07:34 AM
Hey Tonchi!
That's a great question! Asynchronous calls are made, but we don't wait for them to complete. It doesn't always have to mean that we are waiting for something to come back, but rather that we are waiting for something to complete. It also doesn't always have to mean that we are doing it to benefit a user interface, though it is often used for that.
The intent behind asynchronous calls, is to allow a developer to focus on more than one thing at a time. This often makes it feel like more than one thing is happening at a time, as in for example, executing multiple threads at the same time. This is only partially true.
See, in my very basic example, let's just assume that a standard program can only do one thing at a time.
this might look like this:
task_a runs, then b, then c. All after one another. And in most cases, this is exactly what you want to do. Here's what I mean.
I mean, it stands to reason, that you would want to wait for get_name to return, before you do something with it. if you were to execute this asynchronously, this wouldnt make sense. Since the call to do_something_with_name could easily execute before get_name() completed.
So if you were to execute that asynchronously, you would expect to do so more like this:
So, this would call begin_get_name, and when the execution completed, it would call back on_getname_complete. So then you would do something with the name, AFTER you got it. Whenever it happened to come back.
If your following, you can tell right away, that this is somewhat inefficient. And I'd agree in this specific example. This style of programming is normally done to make a bottleneck, less a pain in the neck. If you had to execute a very long process, it's more efficient to have something interrupted when that process completes, rather than to wait for it. Especially if that process is executing somewhere else, like on a server or something.
This isn't unlike having it used to benefit user interfaces, because if you had a process that took 10 seconds to complete, your UI would 'lock up' for 10 seconds waiting for it to complete.
It's also important to note that this tool isn't best suited for all situations, and definitely comes equipped with inherent dangers. For example, you need to program expecting weird things to happen. Say for example, what if the process never completes? If your application disables an important UI element until the end signal is received, you've got a potential problem.
You also need to be aware of specific types of race conditions. And while this isn't nearly as chaotic as running multiple worker threads simultaneously, depending on how you write your application, you could end up with issues.
I'd be happy to respond to specific questions, it's really a large topic! And I can also provide an example of something I've written, showing how Asynchronous programming works.
Example Wrapper for an IRC connection:
That's a great question! Asynchronous calls are made, but we don't wait for them to complete. It doesn't always have to mean that we are waiting for something to come back, but rather that we are waiting for something to complete. It also doesn't always have to mean that we are doing it to benefit a user interface, though it is often used for that.
The intent behind asynchronous calls, is to allow a developer to focus on more than one thing at a time. This often makes it feel like more than one thing is happening at a time, as in for example, executing multiple threads at the same time. This is only partially true.
See, in my very basic example, let's just assume that a standard program can only do one thing at a time.
- Task A
- Task B
- Task C
this might look like this:
void Main() {
task_a();
task_b();
task_c();
}
task_a runs, then b, then c. All after one another. And in most cases, this is exactly what you want to do. Here's what I mean.
void Main() {
string name = get_name();
do_something_with_name(name);
}
I mean, it stands to reason, that you would want to wait for get_name to return, before you do something with it. if you were to execute this asynchronously, this wouldnt make sense. Since the call to do_something_with_name could easily execute before get_name() completed.
So if you were to execute that asynchronously, you would expect to do so more like this:
void Main() {
begin_get_name(on_getname_complete);
}
void on_getname_complete(IAsyncResult result) {
do_something_with_name = end_get_name(result);
}
So, this would call begin_get_name, and when the execution completed, it would call back on_getname_complete. So then you would do something with the name, AFTER you got it. Whenever it happened to come back.
If your following, you can tell right away, that this is somewhat inefficient. And I'd agree in this specific example. This style of programming is normally done to make a bottleneck, less a pain in the neck. If you had to execute a very long process, it's more efficient to have something interrupted when that process completes, rather than to wait for it. Especially if that process is executing somewhere else, like on a server or something.
This isn't unlike having it used to benefit user interfaces, because if you had a process that took 10 seconds to complete, your UI would 'lock up' for 10 seconds waiting for it to complete.
It's also important to note that this tool isn't best suited for all situations, and definitely comes equipped with inherent dangers. For example, you need to program expecting weird things to happen. Say for example, what if the process never completes? If your application disables an important UI element until the end signal is received, you've got a potential problem.
You also need to be aware of specific types of race conditions. And while this isn't nearly as chaotic as running multiple worker threads simultaneously, depending on how you write your application, you could end up with issues.
I'd be happy to respond to specific questions, it's really a large topic! And I can also provide an example of something I've written, showing how Asynchronous programming works.
Example Wrapper for an IRC connection:
/// <summary>
/// Wrapps Socket, suitable for IRC Session
/// </summary>
[CLSCompliant(true)]
public sealed class IrcConnection : object, IDisposable {
/// <summary>
/// Connection to IRC Server
/// </summary>
private Socket m_socket;
/// <summary>
/// Used to buffer incomming responses
/// </summary>
private StringBuilder m_response_buffer;
/// <summary>
/// Initialize IrcConnection
/// </summary>
internal IrcConnection()
: base() {
Response += onResponse;
return;
}
/// <summary>
/// Indicates whethere we're connected to teh server or not
/// </summary>
public bool Connected {
get {
return m_socket.Connected;
}
}
/// <summary>
/// Signal Indicating a response from the server
/// </summary>
public event SimpleResponseHandler Response;
/// <summary>
/// Connect to the server
/// </summary>
/// <param name="server_endpoint">
/// A <see cref="EndPoint"/>
/// </param>
/// <returns>
/// A <see cref="System.Boolean"/>
/// </returns>
public bool connect(EndPoint server_endpoint) {
if (m_socket != null) disconnect();
m_socket = create_socket();
m_socket.Connect(server_endpoint);
if (m_socket.Connected) {
m_response_buffer = new StringBuilder();
recieve();
}
return m_socket.Connected;
}
/// <summary>
/// Disconnect from the server, point socket to null
/// </summary>
/// <returns>true if disconnect was successful</returns>
public bool disconnect() {
if (m_socket != null) {
if (m_socket.Connected)
m_socket.Disconnect(false);
m_socket = null;
}
return m_socket == null;
}
/// <summary>
/// Send data to the server
/// </summary>
/// <param name="command">command to send to the server</param>
public void send(string command) {
byte[] sendBuffer = Settings.DEFAULT_ENCODING.GetBytes(command + "\r\n"); //Appending the \r\n so you dont have to
try {
m_socket.BeginSend(sendBuffer, 0, sendBuffer.Length, SocketFlags.None, onSendComplete, sendBuffer);
} catch (Exception) {
return;
}
return;
}
/// <summary>
/// Recieve data from the server
/// </summary>
private void recieve() {
byte[] recieveBuffer = new byte[512];
try {
m_socket.BeginReceive(recieveBuffer, 0, recieveBuffer.Length, SocketFlags.None, onRecvComplete, recieveBuffer);
} catch (Exception) {
disconnect();
return;
}
return;
}
/// <summary>
/// Async Send Complete, this doesnt do much.
/// </summary>
/// <param name="result">Async Results</param>
private void onSendComplete(IAsyncResult result) {
byte[] sendBuffer = (byte[])result.AsyncState;
int sent = m_socket.EndSend(result);
if (sent != sendBuffer.Length) {
disconnect();
throw new Exception("Send Failed!");
}
return;
}
/// <summary>
/// Async Recieve Complete,
/// This is a major driving method in this system.
/// </summary>
/// <param name="result">Async Result</param>
private void onRecvComplete(IAsyncResult result) {
int recv = 0;
byte[] recieveBuffer = (byte[])result.AsyncState;
try {
recv = m_socket.EndReceive(result);
} catch (Exception) {
disconnect();
return;
}
if (recv == 0) return;
m_response_buffer.Append(
Settings.DEFAULT_ENCODING.GetString(recieveBuffer, 0, recv));
foreach (string line in processResponseBuffer())
Response(line); //Notify Client of response
recieve(); //Set up recieve again
return;
}
/// <summary>
/// Alternative Way of handling messages
/// </summary>
/// <returns>array of responses</returns>
/// <remarks>
/// Handling this is more of a cached way, because it seems that the server
/// sends messages continuously, so there are times when messages will come through, that
/// look like garbage
/// </remarks>
private string[] processResponseBuffer() {
List<string> responses = new List<string>();
while (m_response_buffer.ToString().IndexOf("\r\n") != -1) {
string buf = m_response_buffer.ToString();
responses.Add(buf.Substring(0, buf.IndexOf("\r\n")));
m_response_buffer.Remove(0,
buf.Substring(0, buf.IndexOf("\r\n")
).Length + 2); //Remove message, plus the CRLF pair
}
return responses.ToArray();
}
/// <summary>
/// Internal Trigger Handler
/// </summary>
/// <param name="response">response from server</param>
/// <remarks>
/// This is primarily here, simply to avoid a null reference exception, in the unlikely event that
/// that this event is not being subscribed to.
/// </remarks>
private void onResponse(string response) {
return;
}
/// <summary>
/// Create our socket
/// </summary>
/// <returns>
/// A <see cref="Socket"/>
/// </returns>
private Socket create_socket() {
return new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
}
#region IDisposable Members
/// <summary>
/// Dispose Pattern
/// </summary>
public void Dispose() {
disconnect();
return;
}
#endregion
}
#7
Posted 04 May 2011 - 09:02 AM
and what with those tags???
#8
Posted 04 May 2011 - 09:05 AM
tags? do you mean the attribute CLSCompliant?
or do you mean the XML comments?
The XML Comments are used to generate a really raw form of documentation, well they are actually combined into an XML Comment file at build time, and I use a tool called sandcastle, which compiles that into something readable.
just hit '///' on top of something like a method, and it will template them out for you to fill in. It's probably a good practice to get into.
or do you mean the XML comments?
The XML Comments are used to generate a really raw form of documentation, well they are actually combined into an XML Comment file at build time, and I use a tool called sandcastle, which compiles that into something readable.
just hit '///' on top of something like a method, and it will template them out for you to fill in. It's probably a good practice to get into.
#9
Posted 04 May 2011 - 10:16 AM
i mean the tag <summary>
why is that imporatant and is there anything else that can be inside that tag...
is that important part of asynchronous programming???
why is that imporatant and is there anything else that can be inside that tag...
is that important part of asynchronous programming???
#10
Posted 04 May 2011 - 11:57 AM
no, it's not important to asynchronous programming.
the async pattern is basically this
Call Begin Execute Async Process
Continue on Current Thread
Current thread will be interrupted when async process completes
the interrupt callback kind of works like the method stub you use when you click a button. It's very similar.
The XML in the comments you're seeing, is something I do to most everything I write. It has nothing to do with async programming at all. The comments do however give clues to why I wrote what I wrote, so you should read em.
the async pattern is basically this
Call Begin Execute Async Process
Continue on Current Thread
Current thread will be interrupted when async process completes
the interrupt callback kind of works like the method stub you use when you click a button. It's very similar.
The XML in the comments you're seeing, is something I do to most everything I write. It has nothing to do with async programming at all. The comments do however give clues to why I wrote what I wrote, so you should read em.
#11
Posted 04 May 2011 - 12:54 PM
what are methods to call begin execute async process and what are methods for interrupting current thread and how can i see result???
#12
Posted 04 May 2011 - 01:33 PM
Hey Tonchi! Another great question!
Some API's already have asynchronous patterns implemented. If you look at my example, you can see this in the Sockets API. But in truth, you can call almost anything asynchronously.
The specifics to how you call it, and how you extract the return value, largely depend on what you're calling, and how you've implemented your solution.
It all starts with a delegate. A delegate is a type-safe function pointer. So what that means, is that you describe a method, so that you can reference that method.
now, with that delegate type, you can make an instance of a ReturnStringHandler delegate.
from this point, you can simple call:
just make sure on_invoke_complete looks like this
sorry, I know it's sparse, I'm trying to give you a full circle example. Do you have something specific you'd like to call asynchronously?
Some API's already have asynchronous patterns implemented. If you look at my example, you can see this in the Sockets API. But in truth, you can call almost anything asynchronously.
The specifics to how you call it, and how you extract the return value, largely depend on what you're calling, and how you've implemented your solution.
It all starts with a delegate. A delegate is a type-safe function pointer. So what that means, is that you describe a method, so that you can reference that method.
delegate String ReturnStringHandler();
now, with that delegate type, you can make an instance of a ReturnStringHandler delegate.
ReturnStringHandler myDelegate = new ReturnStringHandler(some_method); //where some_method, is a method that takes no arguments, and returns a string
from this point, you can simple call:
myDelegate.Invoke(); //to call it in a standard way or myDelegate.BeginInvoke(on_invoke_complete, null); //to call it asynchronously
just make sure on_invoke_complete looks like this
void on_invoke_complete(IAsyncResult result) {
string value = myDelegate.EndInvoke(result);
//value is the value you're looking for
}
sorry, I know it's sparse, I'm trying to give you a full circle example. Do you have something specific you'd like to call asynchronously?
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users


Sign In
Create Account


Back to top









