oTaiYangXingChen1
zx_billy
2019-07-09 20:55
采纳率: 50%
浏览 1.3k

C#多线程读同一文件,写多个文件并更新进度条

代码的目的是启动3个task,通过调用C DLL中getSWMMout方法读取同一二级制文件中不同部分,写3个文件,NdeExtract和LinkExtract方法和SubExtract方法代码结构一致。
当多个checkBox都选中时,报错代码:托管调试助手 "FatalExecutionEngineError":“运行时遇到了错误。此错误的地址为 0x6cb8f121,在线程 0x3f58 上。错误代码为 0xc0000005。此错误可能是 CLR 中的 bug,或者是用户代码的不安全部分或不可验证部分中的 bug。此 bug 的常见来源包括用户对 COM-interop 或 PInvoke 的封送处理错误,这些错误可能会损坏堆栈。”。请问怎么解决呢?在博客园提过同样的问题,但回答不太明白,如果3个task顺序执行应该怎么修改呢?
代码如下:

        //  Extract subcatch output values if checked
        if (chkSub.IsChecked == true)
        {
            progressBar1.Value = 0;
            //  define file path for subcatchment extraction
            string subcatchOutPath = "subcatch.txt";
            //  instaniate a task for extraction
            var subTask = SubExtract(subcatchOutPath);
        }
        //  Extract node output values if checked
        if (chkNode.IsChecked == true)
        {
           progressBar2.Value = 0;
            //  define file path for node extraction
            string nodeOutPath = "node.txt";
            //  instaniate a task for extraction
            var nodeTask = NodeExtract(nodeOutPath);
        }
        //  Extract linke output values if checked
        if (chkLink.IsChecked == true)
        {
            progressBar3.Value = 0;
            //  define file path for link extraction
            string linkOutPath = "link.txt";
            //  instaniate a task for extraction
            var linkTask = LinkExtract(linkOutPath);
        }

        async Task SubExtract(string outPathSub)
        //
        //  Purpose: extract variable outcome for subcatchment
        //
        {
            int errSubID;  
            int cntSub = 0;  
            int sumSubPrd = Nsubcatch * extNperiod;  //  total for subcatchment outcome
            float subValue = 0F;    //  outcome value for subcatchment extraction
            //  create file stream for writing file
            FileStream fsSubcatch = new FileStream(outPathSub, FileMode.Create);
            StreamWriter swSubcatch = new StreamWriter(fsSubcatch);

            await Task.Run(() =>
            {
                for (int i = 0; i < Nsubcatch; ++i)
                {
                    for (int j = 1; j <= extNperiod; ++j)
                    {
                        for (int k = 0; k < NsubcatchVar; ++k)
                        {
                            //  getSWMMout为C DLL中方法
                            errSubcatch = getSWMMresult(SUBCATCH, i, k, j, ref subValue);
                        }
                        //  update progressbar and textBlock value
                        cntSub++;
                        progressBar1.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,
                            (Action)delegate ()
                            {
                                progressBar1.Value = cntSub * 100 / sumSubPrd;
                            });
                    }
                }
                //  empty buffer
                swSubcatch.Flush();
                //  close stream
                swSubcatch.Close();
                fsSubcatch.Close();
                GC.Collect();
            });
        }
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • oTaiYangXingChen1
    zx_billy 2019-07-11 22:05
    已采纳

    通过调用改写WinForm的DoEvents()的一个类和thread.join()可以实现线程排序运行

    点赞 评论
  • dabocaiqq
    dabocaiqq 2019-07-09 22:15
    点赞 评论
  • xingyuewubian258
    xingyuewubin 2019-07-12 22:07

    可以使用System.Threading.ThreadPool.QueueUserWorkItem 这个方法可以让线程顺序进行

    点赞 评论

相关推荐