You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C#实现Polarion测试管理Web服务的并行执行?

问题分析与解决方案

你遇到的随机异常问题,核心原因大概率是线程安全问题,结合你的代码来看,主要有以下几个可能的点:

  • 共享的UploadDataTask实例被多个并行线程同时调用,如果这个类的UploadData方法内部维护了非线程安全的状态(比如未同步的字段、共用的非线程安全对象),就会导致竞态条件,引发随机异常。
  • 传入UploadData的参数(比如con、testRun等)如果本身不是线程安全的对象(例如数据库连接、Polarion的客户端实例),多线程共用会导致资源冲突。
  • 并行调用Web服务时,可能触发Polarion服务端的并发限制,或者客户端未正确处理多请求的会话/连接。

针对性修复方案

  1. 每个线程使用独立的UploadDataTask实例
    避免多个线程共享同一个实例,把实例创建放到循环体内:
var parallelOptions = new ParallelOptions 
{ 
    MaxDegreeOfParallelism = 3 
};

Parallel.For(0, testRecordsAfterAdding.Length, parallelOptions, i =>
{
    // 每个线程创建独立的任务实例
    var task = new UploadDataTask();
    var test = testRecordsAfterAdding[i];
    task.UploadData(test, i, con, idTestCase, ruUri, testRun, textTestRun, userUriExecuted);
    Console.WriteLine("Thread" + Thread.CurrentThread.ManagedThreadId);
});
  1. 确保传入的参数线程安全
  • 如果con是数据库连接,不要共享单个连接,改为每个线程创建新的连接实例(用完及时释放)。
  • 检查Polarion相关的对象(比如testRun)是否支持多线程访问,若不支持,也要为每个线程创建独立实例。
  1. 捕获并记录线程异常
    添加try-catch块捕获每个线程的异常,方便定位具体问题:
Parallel.For(0, testRecordsAfterAdding.Length, parallelOptions, i =>
{
    try
    {
        var task = new UploadDataTask();
        var test = testRecordsAfterAdding[i];
        task.UploadData(test, i, con, idTestCase, ruUri, testRun, textTestRun, userUriExecuted);
        Console.WriteLine("Thread" + Thread.CurrentThread.ManagedThreadId + " completed index " + i);
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} failed at index {i}: {ex.Message}\n{ex.StackTrace}");
    }
});
  1. 改用异步并行处理(更适合Web服务调用场景)
    由于Web服务调用是I/O密集型操作,使用Task.WhenAll比Parallel.For更高效,也能更好地处理异步资源:
var tasks = new List<Task>();
for (int i = 0; i < testRecordsAfterAdding.Length; i++)
{
    int index = i; // 捕获循环变量避免闭包问题
    tasks.Add(Task.Run(async () =>
    {
        try
        {
            var task = new UploadDataTask();
            var test = testRecordsAfterAdding[index];
            // 如果UploadData可以改为异步方法,建议用await调用
            await task.UploadDataAsync(test, index, con, idTestCase, ruUri, testRun, textTestRun, userUriExecuted);
            Console.WriteLine("Thread" + Thread.CurrentThread.ManagedThreadId + " completed index " + index);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} failed at index {index}: {ex.Message}\n{ex.StackTrace}");
        }
    }));
}
await Task.WhenAll(tasks);

注意:如果UploadData不是异步方法,可以封装成异步,或者直接调用,但异步并行更适合I/O场景。

内容的提问来源于stack exchange,提问作者user20120254

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 23:27:15