Re: Can't find the DbAsyncResult type. What's going on?

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



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.
.



Relevant Pages

  • Generics question.The problem still exists.
    ... int is best,use only 30-50ms,other three do as expected. ... delegate void Method; ... static void DrawBar(int index, TimeSpan time, string text) ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: C++ COM object calling C# delegate callback causes crash
    ... Where the delegate is passed in a different way. ... public interface IDVBSubtitle ... public static void SetFilter{ ... With this change it actually works, the callback is now called as ...
    (microsoft.public.dotnet.framework.interop)
  • Re: An interesting/annoying problem involving callbacks and native C and C#
    ... The other one, that I suspected was caused by a moved delegate, is ... delegate void DateCallBack(ref int y, ref int m, ref int d, ref ... extern static void InitStruct ...
    (microsoft.public.dotnet.languages.csharp)
  • C++ COM object calling C# delegate callback causes crash
    ... I have it setup passing a delegate to the native code. ... the native code calls the callback function the application crashes. ... STDMETHOD(int* count) PURE; ...
    (microsoft.public.dotnet.framework.interop)
  • Re: Delegates question
    ... PrintMessage() - which is all the delegate is doing. ... private delegate int GetCountDelegate ... static void LongRunningMethod ...
    (microsoft.public.dotnet.languages.csharp)