c#:使用相同变量的多个事件的单个处理程序:最佳实践

本文关键字:处理 单个 程序 最佳 事件 变量 | 更新日期: 2023-09-27 17:51:12

考虑下一个代码。这是一个临时的一次性解决方案(跳过了很多逻辑,代码本身也简化了),但是在我编写它的时候,我想到了一些问题。

它从uri中检索文件,如果从文件夹'j'检索时出现错误,它将停止从该文件夹中进一步检索。

据我所知,这段代码是不是线程安全?虽然它看起来对我来说很好,但出于好奇心和自我教育(因为我几乎没有多线程的经验),我想一劳永逸地弄清楚:

  1. openedConnectionsfailed(实际上也存在Remove)变量受到数据竞赛或其他东西的威胁吗?
  2. 如果它不是线程安全的,使它安全的最佳实践是什么?在哪里添加lock s等等?
  3. 如果这些变量不存在,是否存在任何类型的不一致?我的意思是,它是好添加DownloadDataCompleted处理程序到几个事件?
  4. DownloadDataCompleted作为专用类的非静态成员并编写webClient.DownloadDataCompleted += new Dedicated().DownloadDataCompleted;是否有一些好处?总的来说,你的观点是:解决这类任务的最好方法是什么?不考虑小的代码优化,但概念(或者我必须写"概念"?o_O)
public class SomeClass
{
    static HashSet<int> failed = new HashSet<int>();
    static int openedConnections = 0;
    static void DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
    {
        openedConnections--;
        if (e.Error != null)
        {
            failed.Add(MyToken(e.UserState).j);
            return;
        }
        //save data
    }
    public void Retrieve()
    {   
        for (int i = 1; i < 10000; i++)
        for (int j = 1; j < 10000; j++)
        {
            if(failed.Contains(j)) continue; 
            WebClient webClient = new WebClient();
            webClient.DownloadDataCompleted += DownloadDataCompleted;
            var uri = string.Format("someuri/{1}/{0}", i, j);
            webClient.DownloadDataAsync(new Uri(uri+".jpg"), /*token here*/);
            openedConnestions++;
            while (openedConnections > 32)Thread.Sleep(111);
        }
    }
}

c#:使用相同变量的多个事件的单个处理程序:最佳实践

    当然。
  1. lock()每次访问前的列表本身(AddRemove)。

  2. 我不太明白你的问题。是否可以对不同的事件有相同的处理程序?当然,谁在乎呢,这只是代码而已。这个特定的处理器是好的吗?实际上不是,整个体系结构也不是,直到TCP级别。这不是Windows设计用来处理TCP连接的方式
  3. 如果你按代码行支付报酬,当然。企业应用程序就是这样编写的。

  4. 如果按浪费的内存或CPU周期付费就更好了。
  5. 从概念上讲,编写web爬虫的传统方法是生成一些线程(这个数量由您的系统定义,它可以处理多少连接),将下载URL推送到数组中(不要忘记lock),并在处理程序中从数组中弹出一个URL(再次不要忘记lock)并同步下载它。当物品用完时,只需返回即可(或者如果您正在动态添加物品,请等待,直到获得更多物品)。