Re: Can't find the DbAsyncResult type. What's going on?
- From: Jeroen Mostert <jmostert@xxxxxxxxx>
- Date: Sat, 19 Sep 2009 13:58:24 +0200
Carl Johansson wrote:
Jeroen,
thanks for your reply! Your solution is very practical and straight forward!
"Jeroen Mostert" <jmostert@xxxxxxxxx> wrote in message news:4ab29fde$0$83248$e4fe514c@xxxxxxxxxxxxxxxxx
As the error is trying to tell you, "itfAR" is not of type "System.Runtime.Remoting.Messaging.AsyncResult". Why would you even assume it is?
Learning about asynchronous delegates I actually picked up this technique from Andrew Troelsen's book "Pro C# 2008 and the .NET 3.5 Platform". There I learned that the delegate instance was lurking inside the System.IAsyncResult parameter of the callback method. Something like this:
using System;
using System.Runtime.Remoting.Messaging;
namespace AsynchronousDelegateDemo
{
class Program
{
delegate int MyDelegate(int i);
static void Main(string[] args)
{
MyDelegate md = new MyDelegate(IncInt);
md.BeginInvoke(1, new AsyncCallback(CallBack), "Press [ENTER] to exit...");
Console.WriteLine("Wait for worker thread to finish...");
Console.ReadLine();
}
static void CallBack(IAsyncResult itfAR)
{
AsyncResult ar = (AsyncResult)itfAR;
MyDelegate md = (MyDelegate)ar.AsyncDelegate;
int i = md.EndInvoke(itfAR);
Console.WriteLine("\ni: {0}", i);
Console.Write(itfAR.AsyncState);
}
static int IncInt(int i)
{
System.Threading.Thread.Sleep(3000);
i++;
return i;
}
}
}
I thought it was rather neat (Uh?)
This technique doesn't generalize (it applies only to .BeginInvoke()), so while neat, it's not particularly useful. I recommend you focus on the general pattern for asynchronous callbacks instead, where you can use only IAsyncResult and have no knowledge of the actual type.
Anyway, using your approach, which I guess is the only approach in this context, I could create a new class or struct named "CallbackData", let is state data point to the delegate instance as well as my arbitrary state data and pass an instance of it to the "stateObject" parameter.This is the usual approach. On the other hand, because delegates can represent instance methods as well as static methods, you don't need to pass state if there is only ever one callback active, as you can just make it part of the object the delegate belongs to:
class Foo {
int state1;
string state2;
void Bar() {
...
command.BeginExecuteReader(commandComplete, command);
...
}
void commandComplete(IAsyncResult asyncResult) {
SqlCommand command = (SqlCommand) asyncResult.AsyncState;
using (var reader = command.EndExecuteReader(asyncResult)) {
// use state1 and state2 here
}
}
}
But because you don't know when "commandComplete" executes, this code is not thread-safe and it becomes hard to reason about the state. This is why you usually encapsulate the state the callback needs in a separate object that's not subject to these issues.
--
J.
.
- References:
- Can't find the DbAsyncResult type. What's going on?
- From: Carl Johansson
- Re: Can't find the DbAsyncResult type. What's going on?
- From: Jeroen Mostert
- Re: Can't find the DbAsyncResult type. What's going on?
- From: Carl Johansson
- Can't find the DbAsyncResult type. What's going on?
- Prev by Date: Re: Can't find the DbAsyncResult type. What's going on?
- Next by Date: Resizing splitter panels
- Previous by thread: Re: Can't find the DbAsyncResult type. What's going on?
- Next by thread: DataSet help
- Index(es):
Relevant Pages
|