首页 文章

一个较长的呼叫导致所有并行循环暂停或阻止

提问于
浏览
0

我在Parallel.ForEach中调用VB 6.0 dll并期望所有调用同时启动,或者至少有两个调用基于我的PC核心或线程池中的线程可用性

VB6 dll

Public Function DoJunk(ByVal counter As Long, ByVal data As String) As Integer
    Dim i As Long
    Dim j As Long
    Dim s As String

    Dim fno As Integer
    fno = FreeFile
    Open "E:\JunkVB6Dll\" & data & ".txt" For Output Access Write As #fno
    Print #fno, "Starting loop with counter = " & counter
    For i = 0 To counter
        Print #fno, "counting " & i
    Next

    Close #fno
    DoJunk = 1
End Function

正在从调用者传递计数器以控制调用的执行时间,并且正在编写文件以使其成为基于IO的进程 .

C#来电

private void ReportProgress(int value)
{
    progressBar.Value = value;
    //progressBar.Value++;
}

private void button1_Click(object sender, EventArgs e)
{
    progressBar.Value = 0;
    counter = 0;
    Stopwatch watch = new Stopwatch();
    watch.Start();

    //var range = Enumerable.Range(0, 100);
    var range = Enumerable.Range(0, 20);

    bool finished = false;


    Task.Factory.StartNew(() =>
    {
        Parallel.ForEach(range, i =>
        {
            #region COM CALL
            JunkProject.JunkClass junk = new JunkProject.JunkClass();
            try
            {
                Random rnd = new Random();
                int dice = rnd.Next(10, 40);

                int val = 0;
                if (i == 2)
                    val = junk.DoJunk(9000000, i.ToString());
                else
                    val = junk.DoJunk(dice * 10000, i.ToString());
                System.Diagnostics.Debug.Print(junk.GetHashCode().ToString());

                if (val == 1)
                {
                    Interlocked.Increment(ref counter);
                    progressBar.Invoke((Action)delegate { ReportProgress(counter); });
                }
                junk = null;
            }
            catch (Exception excep)
            {
                i = i;
            }
            finally { junk = null; }
            #endregion
        });
    }).ContinueWith(t =>
    {
        watch.Stop();
        MessageBox.Show(watch.ElapsedMilliseconds.ToString());
    });
}

此行使特定呼叫的时间比其他呼叫更长 .

val = junk.DoJunk(9000000, i.ToString());

这里第二个进程导致Parallel.ForEach内的所有调用都停止,即除非第二个调用完成,否则不会创建其他文件 .

这是预期的行为还是我做错了什么?

1 回答

  • 0

    正如@John Wu建议你可以创建AppDomain以允许COM在不同的App Domain上运行,我相信你可以像这样运行你的并行 .

    Parallel.ForEach(range, i =>
            {
                AppDomain otherDomain = AppDomain.CreateDomain(i.ToString());
                otherDomain.DoCallBack(delegate
                {
                    //Your COM call
                });
            });
    

相关问题