c# - 在 C# 中异步运行多个委托(delegate)并等待响应

标签 c# delegates

我有一个网址表,我需要循环遍历、下载每个文件、更新表并返回结果。我想一次运行最多 10 个下载,因此我正在考虑使用委托(delegate),如下所示:

DataTable photos;
bool scanning = false,
    complete = false;
int rowCount = 0;

public delegate int downloadFileDelegate();

public void page_load(){

    photos = Database.getData...        

    downloadFileDelegate d = downloadFile;

    d.BeginInvoke(downloadFileComplete, d);
    d.BeginInvoke(downloadFileComplete, d);
    d.BeginInvoke(downloadFileComplete, d);
    d.BeginInvoke(downloadFileComplete, d);
    d.BeginInvoke(downloadFileComplete, d);

    while(!complete){}

    //handle results...

}

int downloadFile(){

    while(scanning){} scanning = true;

    DataRow r;

    for (int ii = 0; ii < rowCount; ii++) {

        r = photos.Rows[ii];

        if ((string)r["status"] == "ready"){

            r["status"] = "running";

            scanning = false; return ii;                

        }

        if ((string)r["status"] == "running"){

            scanning = false; return -2;                

        }

    }

    scanning = false; return -1;        

}

void downloadFileComplete(IAsyncResult ar){

    if (ar == null){ return; }

    downloadFileDelegate d = (downloadFileDelegate)ar.AsyncState;

    int i = d.EndInvoke(ar);

    if (i == -1){ complete = true; return; }      


    //download file...

    //update row
    DataRow r = photos.Rows[i];

    r["status"] = "complete";

    //invoke delegate again
    d.BeginInvoke(downloadFileComplete, d);

}

但是,当我运行此命令时,运行 5 所需的时间与运行 1 所需的时间相同。我预计它会快 5 倍。

有什么想法吗?

最佳答案

您看起来正在尝试使用无锁同步(使用 while(scanning) 检查在函数开始时设置的 bool 值并在结束时重置),但所有这些都成功了所做的只是一次只运行一次检索。

  1. 您是否有理由不希望它们同时运行?这似乎是你练习的全部要点。我看不出其中的原因,所以我会完全丢失扫描标志(以及相关的逻辑)。
  2. 如果您打算采用这种方法,您的 bool 标志需要声明为 volatile (否则它们的读取可能会被缓存,您可能会无休止地等待)
  3. 您的数据更新操作(更新 DataRow 中的值)必须在 UI 线程上进行。您必须将这些操作封装在 Control.InvokeControl.BeginInvoke 调用中,否则您将跨线程边界与控件进行交互。
  4. BeginInvoke 返回一个 AsyncWaitHandle。将其用于操作全部完成时将发生的逻辑。像这样的东西

-

WaitHandle[] handles = new WaitHandle[]
{
    d.BeginInvoke(...),
    d.BeginInvoke(...),
    d.BeginInvoke(...),
    d.BeginInvoke(...),
    d.BeginInvoke(...)
}

 WaitHandle.WaitAll(handles);

这将导致调用线程阻塞,直到所有操作完成。

关于c# - 在 C# 中异步运行多个委托(delegate)并等待响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2365718/

相关文章:

iOS Framework Delegate 和 IBAction 没有在 Swift 中被调用

iphone - 找不到我的自定义委托(delegate)的协议(protocol)声明

c# Delegate.BeginInvoke() 和线程 ID

c# - switch 中的多个字符串比较

c# - 获取 Predicate<T> 属性信息

c# - 防止 ASP.NET Web 应用程序上的 SQL 注入(inject)

c# - 将一个对象分配给同一类的另一个对象

ios - iOS 中的递归委托(delegate)——如何实现?

c# - 在代码中修改 XAML 中的行属性集

jquery body委托(delegate)mouseover和mouseout同时触发