If you control B, then Rob Prouse or Brody's answers will work fine.
But what if you can't change B at all? In that case, you can always wrap a method in a delegate of your own making, as long it's signature matches that of the signature of the target method.
So, say you have a class instance named B with a public method named b() (from the B dll assembly, of course). Class A in the A application can call it asynchronously like this:
public class A
{
delegate void BDelegate();
public void BegineBMethod()
{
BDelegate b_method = new BDelegate(B.b);
b_method.BeginInvoke(BCallback, null);
}
void BCallback(IAsyncResult ar)
{
// cleanup/get return value/check exceptions here
}
}