AiDaRLING

导航

c#开发中所遇到的问题及解决方案记录

**一、Cli.Wrap支持conda环境运行python**

    1、我们将两个命令 conda activate ai-cfd 和 python 用分号隔开,然后将整个命令字符串包含在双引号中,作为 -Command 参数的值。
    
     var cmd =
                 Cli.Wrap("PowerShell")
                .WithValidation(CliWrap.CommandResultValidation.None)
                .WithWorkingDirectory(Path.Combine(sourcePath, filePath))
                 .WithArguments($"-Command \"conda activate ai-cfd; python {pythonCmd}\"");
                RunShellLog(pythonCmd.ToString());
                var res = await cmd.WithStandardOutputPipe(PipeTarget.ToDelegate(async s =>
                {
                    await plugInStartDto.Msgfunc(s);
                    if (s.Contains("PowerShell", StringComparison.OrdinalIgnoreCase)) await plugInStartDto.Msgfunc(s);
                    if (s.Contains("Microsoft", StringComparison.OrdinalIgnoreCase)) await plugInStartDto.Msgfunc(s);
                    if (s.Contains("异常"))
                    {
                        await plugInStartDto.Msgfunc(s);
                    }
                }))
                .WithStandardErrorPipe(PipeTarget.ToDelegate(async s =>
                {
                    await plugInStartDto.Msgfunc(s);
                })).ExecuteAsync();
                
                
**二、 调用ComputeNode无回调至控制台原因**

    1、节点使用http,项目回调使用的是https请求,post请求会抛出The SSL connection could not be established"异常,需要把*.module .userHttps()去掉
    2、launchSettings.json 修改applicationUrl为http 
    
**三、abp工作单元事务 await UnitOfWorkManager.Current.CompleteAsync();**
 
    1、如果一个工作单元的方法(使用了UnitOfWork特性声明的方法)调用另一个工作单元的方法,那么它们共享相同的连接和事务。第一个方法管理连接,其他方法使用连接。这个对于运行在相同线程的方法是成立的(对于web应用则是相同的请求
    2、 需使用 await UnitOfWorkManager.Current.CompleteAsync();
   
**四、在C#中,如果子类继承自父类,那么子类对象也包含了父类对象的所有特性和属性**

    1、在这种情况下,person对象赋值给了student对象,并且student对象继承了person的所有属性和方法。但是,
    2、在这种情况下,将Person类型赋值给Student类型需要一些类型转换。使用**as**关键字可以进行类型转换,并将Person对象转换为Student对象。
    3、如果要确保父类对象可以转换为子类对象,可以使用**is**关键字进行判断:
![1679632231883](/attachments/6a8a7cd5-556c-4d19-99e5-bb8be4839c9d)
![image](/attachments/124f83ab-7da0-4b2c-a9d5-8aec075c4e89)

**五、ObjectMapper.Map<BPosMatDto,BSupPositiveDto>(supMat);** 达到父类子类数据的一个转换

      1、使用ObjectMapper达到父类赋值子类对象
        重点: 需在 *AutoMapperProfile.cs :CreateMap<BPosMatDto, BSupPositiveDto>().ReverseMap(); 
        

**六、独立项目打包**

 

     最新:dotnet publish -r <runtime_identifier> -c Release --self-contained

 

  • <runtime_identifier> 是目标平台的标识符,例如 win-x64、linux-x64、osx-x64 等。
  • -c Release 指定发布配置为 Release 模式。
  • --self-contained 参数表示生成一个独立部署的应用程序包。
  
      1、dotnet publish -c Release -r win-x64 /p:PublishSingleFile=true
       其中,
       -c Release表示发布 Release 版本数据;
       -r win-x64表示发布构建为 Windows x64 平台应用;
       /p:PublishSingleFile=true表示编译生成的文件只有一个可执行文件。
       
      2、dotnet publish -c Release -r win-x64 /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true /p:PublishTrimmed=true
       /p:IncludeNativeLibrariesForSelfExtract=true,它指示发布工具将程序所需的本机库文件一并打包到程序包中。 
       
    /p:PublishTrimmed=true,它指示打包工具削减应用程序的完整度以减小发布大小,并减少不必要的依赖项包括除.net.dll之外的所有.dll
    
   在命令行工具中进入发布文件夹,例如:

   cd bin\Release\netcoreappx.x**\win-x64\publish**

 

   3、dotnet publish -c Release -r win-x64 --self-contained true 

 

        error NETSDK1191: 无法推断属性“PublishSingleFile”的运行时标识符。显式指定 rid。 

        明确指定 --self-contained 或 --no-self-contained 选项,并显式指定运行时标识符(RID)。

   4、dotnet  publish -p:PublishProfile=FolderProfile.pubxml  -o D:\TestPub\GC\9030 /p:PublishSingleFile=true /p:WarningLevel=0

         -o 项目地址

   
**七、解决python运行时找不到xx module但是pip list又有模块的bug**   
   
     1、关于python安装中踩的坑,运行时找不到URLlib3
         https://blog.csdn.net/bingcui/article/details/117666633
         
**八、nuget打包推送命令**
     
     1、配置环境变量 --exe
dotnet nuget push (nuget包名)  -s o:\nuget
        示例:dotnet nuget push  HF.UI.Blazor.Server.1.0.0.7.nupkg  -s o:\nuget
**九、linux打包**

     1、dotnet publish -c Release -r linux-x64
     
**十、linux端口访问**   

     1、当linux服务访问0.0.0.0的时候可以访问 使用ip访问或localhost无法访问 需开放防火墙端口
     iptables -I INPUT -p tcp --dport 5545 -j ACCEPT
     
**十一、Install-Package AspNetCoreRateLimit 限流桶**

    1、 appsettings.json 
    
      "IpRateLimiting": {
        "EnableEndpointRateLimiting": true, //false则全局将应用限制,并且仅应用具有作为端点的规则* 。 true则限制将应用于每个端点,
        "StackBlockedRequests": false, //false则拒绝的API调用不会添加到调用次数计数器上
        "RealIpHeader": "X-Real-IP",
        "ClientIdHeader": "X-ClientId",
        "HttpStatusCode": 429,
        "QuotaExceededResponse": {
          "Content": "{{\"code\":429,\"msg\":\"访问过于频繁,请稍后重试\",\"data\":null,\"success\":false}}",
          "ContentType": "application/json; charset=utf-8",
          "StatusCode": 429
        },
        "GeneralRules": [
          {
            "Endpoint": "*",
            "Period": "1s",
            "Limit": 2
          }
        ]
      },
      "IpRateLimitPolicies": {
        "EndpointRules": [
          {
            "Endpoint": "*",
            "Period": "1s", //期间(时间) 1s 1m 1h 1d 秒分时天
            "Limit": 2  //限制次数
          }
        ]
      }
      
  2、Program.cs
  
        // 添加 AspNetCoreRateLimit 限流服务
        // 存储IP计数器及配置规则
        builder.Services.AddMemoryCache();
        //从appsetting.json加载ip规则
        builder.Services.Configure<IpRateLimitOptions>(config.GetSection("IpRateLimiting"));
        builder.Services.Configure<IpRateLimitPolicies>(config.GetSection("IpRateLimitPolicies"));
        //注入计数器和规则存储
        builder.Services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
        //builder.Services.AddSingleton<IClientPolicyStore, MemoryCacheClientPolicyStore>();
        builder.Services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();

        // 配置(解析器,计数器和生成器)
        builder.Services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
        builder.Services.AddSingleton<IProcessingStrategy, AsyncKeyLockProcessingStrategy>();
        
app.UseIpRateLimiting(); // 启用 IP 限流
        
**十二、python pip安装包导入导出、下载包和离线安装**

        
        ![image](/attachments/cbd0d2eb-bc38-4bf1-bb32-a8830d09db23)
        
       1、下载python对应版本的嵌入资源包放置随意位置

        2、使用pip freeze > requirements.txt # 从虚拟环境中生成requirements.txt 

        3、pip install -r requirements.txt # 从requirements.txt安装依赖

        4、pip download -r requirements.txt #批量下载requirements.txt中的安装包

        5、pip install -r requirements.txt --target D:\HF\Python\Python\Python310\Lib\site-packages 嵌入资源包下的site-packages下

           5.1 pip install -t D:\HF\Python\Python\Python310\Lib\site-packages pandas==1.5.3 指定某个安装包的版本下载至目录

        6、c# 引用 Runtime.PythonDLL = "D:\\HF\\Python\\Python\\Python310\\python310.dll";指定资源包地址

        7、ImportError: DLL load failed while importing _ctypes: 找不到指定的模块。 需要更新某个模块升级

           例: Pandas:确保你正在使用的是 Pandas 的最新版本,因为在较新的版本中,可能已经修复了一些兼容性问题。
            pip install --upgrade pandas



**十三、ef使用Include无法全部返回数据(包括无关联的数据),使用into joinList from resource in joinList.DefaultIfEmpty()可达到返回全部**
 
               //无法返回全部的jobinfo信息
                //query.Include(j => j.Resource).ToList();
                var result = from job in _dbContext.JobInfo
                              join resource in _dbContext.Server
                             on job.VMUUID equals resource.UUID into joinList from resource in joinList.DefaultIfEmpty()
                             select new HQJobInfo
                             {
                                 Id = job.Id,
                                 Name = job.Name,
                                 CondName = job.CondName,
                                 JobType = job.JobType,
                                 CreationTime = job.CreationTime,
                                 ProcessIds = job.ProcessIds,
                                 CalcPath = job.CalcPath,
                                 VMUUID = job.VMUUID,
                                 MainTask = job.MainTask,
                                 Status = job.Status,
                                 CallbackPath = job.CallbackPath,
                                 AmodelId = job.AmodelId,
                                 UserName = job.UserName,
                                 UserId = job.UserId,
                                 Properties = job.Properties,
                                 Cores = job.Cores,
                                 Resource = resource,
                                 Step = job.Step,
                             };

**十四、 将一个对象赋给另一个变量。两个变量指向同一个对象的引用。 使用DeepClone 可作为源数据跟新数据的判断**

 

1、引用nuget包 :<PackageReference Include="DeepCloner" Version="0.10.4" />

2、 var  newData = oldData.DeepClone();   newData 不会被oldData的赋值引用操作所改变,newData 则为源数据

 

 

 

**十五、两个或三个数组进行列合并 **

 

在使用数组中需要三个数组的下标合并可使用 listx.Zip进行列合并  

 

1、 两个数组合并案例:

 

            double[] newX = listx[0].ToArray();
            double[] newY = listy[0].ToArray();
            var all1s = newX.Zip(newY, (x, y) =>
              new double[] { x, y, 0.00 }
            );

 

 

 2、三个数组合并案例:

 

            List<double[]> listx = new List<double[]>();
            List<double[]> listy = new List<double[]>();
            List<double[]> listDetRho = new List<double[]>();

            List<double[]> list = new List<double[]>();
            //合并三个数组
            foreach ((double[] x, double[] y, double[] detRho) in listx.Zip(listy, listDetRho))
            {
                foreach ((double xVal, double yVal, double detRhoVal) in x.Zip(y, detRho))
                {
                    list.Add(new double[] { xVal, yVal, detRhoVal });
                }
            }

 

 

 

**十六、追加 log文件,不会提示占  System.IO.IOException:“The process cannot access the file 'xx.log' because it is being used by another process.”**

 

      System.IO.File.AppendAllLines(logPath, new string[] { s });

 

**十七、ProcessStartInfo 启动异步线程无等待 且通过将 EnableRaisingEvents 属性设置为 true 并添加 Exited 事件的处理程序,可以在进程退出时触发回调函数。

 

        public string CallCommand(string cmd, string powershell = "",int processors = 0, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal)
        {

            string processId = "";
            try
            {
                var sw = Stopwatch.StartNew();
                if (powershell.IsNullOrEmpty())
                {
                    powershell = "PowerShell";
                }
                ProcessStartInfo st = new ProcessStartInfo
                {
                    FileName = powershell,
                    CreateNoWindow = true,
                    ErrorDialog = false,
                    RedirectStandardInput = true,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    UseShellExecute = false,
                    WindowStyle = ProcessWindowStyle.Hidden,

                };
                ConsoleWrite($"{nameof(CallCommand)} ", $"ProcessStartInfo==>{JsonConvert.SerializeObject(st)}");
                Process p = null;
                Task runTask = null;
                try
                {

                    p = Process.Start(st);
                    if (p != null)
                    {
                        processId = p.Id + "";
                        ConsoleWrite($"{nameof(CallCommand)} ", $"processId:{processId}");
                        if (processors > 0)
                        {
                            try
                            {
                                p.ProcessorAffinity = (IntPtr)processors;
                            }
                            catch (Exception ex)
                            {
                                ConsoleWrite($"{nameof(CallCommand)} ", ex.Message + ex.StackTrace, LogLevel.Error);
                            }
                        }
                        p.PriorityClass = priorityClass;
                        //通过将 EnableRaisingEvents 属性设置为 true 并添加 Exited 事件的处理程序,可以在进程退出时触发回调函数。
                        p.EnableRaisingEvents = true;
                        p.Exited += ProcessExited;
                        p.StandardInput.WriteLine(cmd);
                        p.StandardInput.Flush();
                        p.StandardInput.Close();
                    }
                }
                catch (Exception ex)
                {
                    ConsoleWrite($"{nameof(CallCommand)} Error", ex.Message + ex.StackTrace, LogLevel.Error);
                }

                sw.Stop();
            }
            catch (Exception e)
            {
                ConsoleWrite($"{nameof(CallCommand)} Error", e.Message,LogLevel.Error);
            }
            return processId;

        }

 

        // Exited 事件的回调函数
       public void ProcessExited(object sender, EventArgs e)
        {
            ConsoleWrite($"{nameof(ProcessExited)} 进程已退出");
            try
            { // 在此处添加您希望执行的回调操作
                Process process = (Process)sender; // 将 sender 强制转换为 Process 对象
                int exitCode = process.ExitCode; // 获取进程的退出代码
                int processId = process.Id; // 获取进程的id
            }
            catch(Exception xe)
            {
                ConsoleWrite($"{nameof(ProcessExited)} Error", xe.Message, LogLevel.Error);
            }
           
        }

 

**十八、查询时已加入AsNoTracking设置不追踪,UpdateRange更新时还是会报tracked的相关错误?解决方法 context.ChangeTracker.Clear(); 

               _dbContext.ChangeTracker.Clear();
                foreach (var item in infos)
                {
                    _dbContext.Entry(item).State = EntityState.Detached;
                    _dbContext.Update(item);
                }
               
                //_dbContext.Entry(infos).State = EntityState.Detached;
                await _dbContext.SaveChangesAsync(true);

 

十九、不规则json参数转成字典的方式 

 

原json:

展开全部 

解决方法 :

 

var options = new JsonSerializerOptions
{
    AllowTrailingCommas = true
};
var json = JObject.Parse(jsonString);
var sortedData = json["output_data"]["sorted_data"] as JObject;
var dataDict = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, Dictionary<string, Dictionary<string, object>>>>(sortedData.ToString(), options);
results.results_ylb = System.Text.Json.JsonSerializer.Deserialize<Results_YLB>(jsonString, options);
results.results_ylb.output_data.sorted_data = dataDict;

 

 

 

二十、Cli.Wrap日志脚本执行结束时才发送

 

          显式地刷新输出缓冲区:在 Python 脚本中,你可以使用'flush=True'参数来强制刷新输出缓冲区,使得输出立即被发送到标准输出流,而不是等到缓冲区满或脚本执行结束时才发送。例如:

                   print("Some output", flush=True)

 

二十一、Vue build之后启动程序

 

    1、npm install -g http-server  2、cd dist  3、http-server -p 3000 修改端口

posted on 2025-06-16 11:12  AiDaRLING  阅读(74)  评论(0)    收藏  举报