如何将对象设置为 AsyncState 并将其传递给 AsyncCallback 方法

本文关键字:AsyncCallback 方法 AsyncState 对象 设置 | 更新日期: 2023-09-27 18:32:30

两个问题:

  1. 如何将参数传递给AsyncCallback方法?

  2. 如何调用AsyncCallback方法?

以下是背景:

我正在处理.NET Framework 3.5中的一个旧项目。我想创建一个异步方法,在不阻塞当前线程的情况下完成一些工作。由于该项目是旧版本的Async Await关键字不可用,因此我计划在AsyncCallback方法中进行所有并行工作,包括一些数据库查询和api调用。我知道AsyncState可以用来传达论点。因为我需要多个参数,所以我计划将这些参数包含在一个对象中,并将该对象设置为 AsyncState,这样我就可以将 AsyncState 强制转换为要在 AsyncCallback 方法中使用的对象。我没有找到一个好方法。我找到了这个链接,但我不使用HttpWebRequest。

 public Class ArgumentObject
 {
      public string A{get;set;}
      public string B{get;set;}
      ...
 }
 public void CallBack(IAsyncResult result, ArgumentObject arObj)
 {
      Console.WriteLn(arObj.A);
      Console.WriteLn(arObj.B);
 }

以下是调用 AsyncCallBack 方法的代码。

 var argumentsObj=new ArgumentObject{ A="argument1", B="argument2"..};
 AsyncCallback callback = (IAsyncResult result) => CallBack(result, argumentsObj);
 // How do I know it is triggered? I set the break point into CallBack method, but it never goes to there.

任何想法或更正都值得赞赏。

如何将对象设置为 AsyncState 并将其传递给 AsyncCallback 方法

更新:我终于找到了一种传递论点的方法。我使用委托并调用 BeginInvoke 方法。

static int DoSomething(string s, int t)
    {
        Console.WriteLine(s+t.ToString());
        return 0;
    }// this is the delegate method, you can define it anyway.
public delegate int MyDelegate(string s, int t);
MyDelegate x = new MyDelegate(DoSomething);
AsyncCallback callback = new AsyncCallback(CallBack);
var argumentsObj=new ArgumentObject{ A="argument1", B="argument2"..};
IAsyncResult ar = x.BeginInvoke("hello", 12, callback, argumentsObj);
// in my case, the first two parameters are not important, only the last two are important.

现在在回调方法中,我可以将 AsyncState 转换为参数对象:

var obj = (CallBackObj)result.AsyncState;

在 CallBack 方法中,不要忘记调用 EndInvoke 方法,以保证不会泄漏内存或句柄

MyDelegate x = (MyDelegate)((AsyncResult)result).AsyncDelegate;
        x.EndInvoke(result);

不确定此解决方案是否与您的情况相关,但就我而言,我需要一个常见的实用程序异步任务来与调用方一起检查 ITaskHandler 在切换到 UI 线程后是否仍然有效。

现在,如果我在C++我可以简单地将指向对象的引用指针作为参数传递,但在 C# 中,事情可能会变得混乱,所以对我来说最简单的解决方案是为需要实用程序函数的所有类创建一个方法接口。

public interface ITaskHandlerClient
{
    ITaskHandler GetTaskHandler();
}

然后将调用方作为 ITaskHandlerClient 对象传递。

public static async Task<bool> TaskHandlerProgressAsync(ITaskHandlerClient client,
    string text, int progress) { ... }