首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >c#多个后台工作进程相同的方法

c#多个后台工作进程相同的方法
EN

Stack Overflow用户
提问于 2016-07-12 14:10:56
回答 2查看 173关注 0票数 1

我有一个问题,当2-8个后台工作人员访问相同的方法时,会出现问题。下面是一个例子:

代码语言:javascript
复制
int threadnumber = 0;
int retries[] = new int[8];

private XmlDocument GetXML(string ApiUrl, int threadnumber)
        {
            var mySourceDoc = new XmlDocument();
            try
            {
                var httpRequest = (HttpWebRequest)WebRequest.Create(ApiUrl);
                httpRequest.Timeout = 50000;
                if (cb_Proxy.Checked == true)
                {
                    WebProxy germanserver = new WebProxy();
                    Uri newUri = new Uri("http://" + txt_Proxy.Text);
                    germanserver.Address = newUri;
                    httpRequest.Proxy = germanserver;
                }
                var response = (HttpWebResponse)httpRequest.GetResponse();
                var receiveStream = response.GetResponseStream();
                receiveStream.ReadTimeout = 150000;
                mySourceDoc.Load(receiveStream);
                receiveStream.Close();
                retries[threadnumber-1] = 1;
            }
            catch (Exception ex)
            {
                //DialogResult MessBox = MessageBox.Show("Der Server ist nicht erreichbar oder es ist ein anderes Problem mit dem Server aufgetreten. Es wird automatisch 3 mal erneut versucht. Fehlermeldung anzeigen?", "Fehler", MessageBoxButtons.YesNo, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                //if (MessBox == DialogResult.Yes) MessageBox.Show(ex.Message);
                retries[threadnumber - 1]++;
                consoletext = "Fehler: " + ex.Message + "; Neuer Versuch " + retries[threadnumber - 1] + " von Url " + ApiUrl + Environment.NewLine;
                if (threadnumber == 1) workingHelper1.ReportProgress(counterhelper[0]);
                if (threadnumber == 2) workingHelper2.ReportProgress(counterhelper[1]);
                if (threadnumber == 3) workingHelper3.ReportProgress(counterhelper[2]);
                if (threadnumber == 4) workingHelper4.ReportProgress(counterhelper[3]);
                if (threadnumber == 5) workingHelper5.ReportProgress(counterhelper[4]);
                if (threadnumber == 6) workingHelper6.ReportProgress(counterhelper[5]);
                if (threadnumber == 7) workingHelper7.ReportProgress(counterhelper[6]);
                if (threadnumber == 8) workingHelper8.ReportProgress(counterhelper[7]);
                Thread.Sleep(3000);
            }
            finally
            {
                if (retries[threadnumber - 1] > 1 && retries[threadnumber - 1] <= 3) GetXML(ApiUrl, threadnumber);
                if (retries[threadnumber - 1] >= 4) retries[threadnumber] = 1;
            }
            return mySourceDoc;
}

后台工作人员使用生成的url字符串和线程编号1-8调用方法getxml。我的问题是,有时重试次数会达到5或更高。所以我认为后台工作人员有时会访问相同的变量并对其进行计数?

EN

回答 2

Stack Overflow用户

发布于 2016-07-12 14:33:23

通常,允许多个线程同时操作同一对象并不是一个好主意。这肯定会导致被操纵对象的状态发生冲突。

考虑在访问和操作共享变量(即threadnumberretries)的行上使用lock

还要考虑调用方法的方式,因为:

  1. 似乎每个工作线程都需要retries数组中的2个条目(即threadnumberthreadnumber - 1),因此,您不能使用连续的threadnumber值调用GetXML方法,否则您将在retries数组中获得冲突。或者这可能是代码中的一个bug (下面引用)导致了这个问题。

if (retriesthreadnumber -1 >= 4) retriesthreadnumber = 1;

  1. 考虑调用GetXML方法的代码,并确保它不会将相同的threadnumber分配给多个工作进程。
票数 0
EN

Stack Overflow用户

发布于 2016-07-12 16:45:56

这似乎是一个合乎逻辑的失败。现在我已经调试了每个线程和实际的变量内容。所以看起来一切正常,没有任何变量可以被覆盖。

代码语言:javascript
复制
private XmlDocument GetXML(string ApiUrl, int threadnumber)
    {
        object thislock = new object();
        lock (thislock)
        {
            var mySourceDoc = new XmlDocument();
            try
            {
                var httpRequest = (HttpWebRequest)WebRequest.Create(ApiUrl);
                httpRequest.Timeout = 50000;
                if (cb_Proxy.Checked == true)
                {
                    WebProxy proxy = new WebProxy();
                    Uri newUri = new Uri("http://" + txt_Proxy.Text);
                    proxy.Address = newUri;
                    httpRequest.Proxy = proxy;
                }
                var response = (HttpWebResponse)httpRequest.GetResponse();
                var receiveStream = response.GetResponseStream();
                receiveStream.ReadTimeout = 150000;
                mySourceDoc.Load(receiveStream);
                receiveStream.Close();
                retries[threadnumber - 1] = 1;
            }
            catch (Exception ex)
            {
                retries[threadnumber - 1]++;
                if (retries[threadnumber - 1] == 4)
                {
                    consoletext = "Endgültiger Abbruch von Url " + ApiUrl + Environment.NewLine;
                    writeLog("Worker: " + threadnumber + " Endgültiger Abbruch von Url " + ApiUrl);
                }
                else
                {
                    consoletext = "Fehler: " + ex.Message + "; Neuer Versuch " + retries[threadnumber - 1] + " von Url " + ApiUrl + Environment.NewLine;
                    writeLog(ex.Message + "; Versuch: " + retries[threadnumber - 1] + " Thread: " + threadnumber + " URL: " + ApiUrl);
                }
                //DialogResult MessBox = MessageBox.Show("Der Server ist nicht erreichbar oder es ist ein anderes Problem mit dem Server aufgetreten. Es wird automatisch 3 mal erneut versucht. Fehlermeldung anzeigen?", "Fehler", MessageBoxButtons.YesNo, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                //if (MessBox == DialogResult.Yes) MessageBox.Show(ex.Message);

                if (threadnumber == 1) workingHelper1.ReportProgress(counterhelper[0]);
                if (threadnumber == 2) workingHelper2.ReportProgress(counterhelper[1]);
                if (threadnumber == 3) workingHelper3.ReportProgress(counterhelper[2]);
                if (threadnumber == 4) workingHelper4.ReportProgress(counterhelper[3]);
                if (threadnumber == 5) workingHelper5.ReportProgress(counterhelper[4]);
                if (threadnumber == 6) workingHelper6.ReportProgress(counterhelper[5]);
                if (threadnumber == 7) workingHelper7.ReportProgress(counterhelper[6]);
                if (threadnumber == 8) workingHelper8.ReportProgress(counterhelper[7]);
                Thread.Sleep(3000);
            }
            finally
            {
                if (retries[threadnumber - 1] > 1 && retries[threadnumber - 1] <= 3) GetXML(ApiUrl, threadnumber);
                //if (retries[threadnumber - 1] >= 4) retries[threadnumber - 1] = 1;
                else retries[threadnumber - 1] = 1;
            }
            return mySourceDoc;
        }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38321186

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档