V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
justdoitzZ
V2EX  ›  C#

关于 C#调用 DLL 的疑惑

  •  
  •   justdoitzZ · 2023-12-23 17:56:13 +08:00 · 2255 次点击
    这是一个创建于 369 天前的主题,其中的信息可能已经有所发展或是发生改变。

    手头有个文件格式转换的 DLL ,正常一个文件格式转换需要 0.4s

    首先做了一个小程序,读取了目录下的 100 个需要转换的文件的路径信息,然后 100 个依次进行转换,耗时 0.4* 100 = 40s

    然后我把这个小程序复制了一个,成了小程序 2.

    小程序和小程序 2 可以同时双开,进行文件转换。速度也加快了。

    但是当我尝试在一个程序里面使用 task 或者多线程调用 DLL 里面的文件转换函数的时候,就报错了。DLL 内置了加密狗权限查阅功能,此时就异常了。但是很奇怪的是,小程序 1 和小程序 2 可以同时运行,没有出现机密狗权限的问题。

    困扰我好久的问题,有大佬可以解答疑惑吗?

    8 条回复    2023-12-23 21:05:49 +08:00
    xiangyuecn
        1
    xiangyuecn  
       2023-12-23 18:06:43 +08:00
    进程 线程 傻傻分不清
    justdoitzZ
        2
    justdoitzZ  
    OP
       2023-12-23 18:46:56 +08:00
    @xiangyuecn 。。。。刚学 C# 没多久,就会 Debug.WriteLine
    xiangyuecn
        3
    xiangyuecn  
       2023-12-23 19:06:39 +08:00
    直接用 Process 新开两个子进程进行处理完事
    opengps
        4
    opengps  
       2023-12-23 19:45:28 +08:00
    应该是一楼说的问题,反射加载本质类似于拷贝一份到内存里用,所以你多个进程可以并行,但多线程显然程序的内部运行有冲突
    opengps
        5
    opengps  
       2023-12-23 19:50:27 +08:00
    换句话说,如果你非要一个程序处理,那么可以先拷贝多份,然后各个线程调用各自的副本文件
    devliu1
        6
    devliu1  
       2023-12-23 19:58:35 +08:00 via Android
    盲猜 dll 里没有处理好多线程
    justdoitzZ
        7
    justdoitzZ  
    OP
       2023-12-23 21:02:56 +08:00
    @devliu1 这个垃圾 DLL 是个黑箱。感觉按照楼上说的处理
    justdoitzZ
        8
    justdoitzZ  
    OP
       2023-12-23 21:05:49 +08:00   ❤️ 1
    按照兄弟们提供的思路,chatgpt 提供了如下代码,我再调试一下,我感觉可行了
    using System.Diagnostics;

    // ...

    private void button2_Click(object sender, EventArgs e)
    {
    string path = @"c:\Work\temp\123\";
    string[] suffixes = { ".avl", ".sum", ".nsm" };

    FileProcessor fileProcessor = new FileProcessor();
    fileProcessor.ListFilesRecursively(path, suffixes);

    // 获取原始结果
    List<FileInfo> sourceFileInfos = fileProcessor.FileInfos;

    // 创建新的目标文件信息
    List<FileInfo> targetFileInfos = fileProcessor.CreateTargetFileInfos(sourceFileInfos, ".txt");

    int processesCount = 10;

    for (int i = 0; i < processesCount; i++)
    {
    int startIdx = i * targetFileInfos.Count / processesCount;
    int endIdx = (i == processesCount - 1) ? targetFileInfos.Count : (i + 1) * targetFileInfos.Count / processesCount;

    var processFiles = targetFileInfos.GetRange(startIdx, endIdx - startIdx);

    ProcessStartInfo startInfo = new ProcessStartInfo
    {
    FileName = "YourExecutable.exe", // 替换为实际的可执行文件名
    Arguments = $"{string.Join(" ", processFiles.Select(f => $"\"{f.FilePath}\""))}", // 传递文件路径作为参数
    WorkingDirectory = Path.GetDirectoryName(Application.ExecutablePath), // 设置工作目录
    UseShellExecute = false,
    CreateNoWindow = true,
    };

    Process process = new Process { StartInfo = startInfo };
    process.Start();
    }
    }
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5638 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 03:19 · PVG 11:19 · LAX 19:19 · JFK 22:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.