Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .net线程:将自定义类引用作为参数传递_C#_Multithreading_Thread Safety - Fatal编程技术网

C# .net线程:将自定义类引用作为参数传递

C# .net线程:将自定义类引用作为参数传递,c#,multithreading,thread-safety,C#,Multithreading,Thread Safety,我不熟悉.net中的线程,我正在维护一个用MVC5编写的应用程序。 应用程序有一个静态实用程序类,它有一个静态PostRequests方法来处理Web客户端请求。 在这个网页上,我启动了3个线程,它们将调用这个静态方法从3个不同的来源获取数据 每个Webclient请求的超时时间为45秒。但是其中一个线程只打印30秒左右的日志,并且没有完成任务就死了。 我读了几篇文章,其中写到需要使引用变量成为线程安全的,我不知道如何做到这一点。 我的问题是: 该方法是线程安全的吗?我是否在参数或访问变量方面犯

我不熟悉.net中的线程,我正在维护一个用MVC5编写的应用程序。 应用程序有一个静态实用程序类,它有一个静态PostRequests方法来处理Web客户端请求。 在这个网页上,我启动了3个线程,它们将调用这个静态方法从3个不同的来源获取数据

每个Webclient请求的超时时间为45秒。但是其中一个线程只打印30秒左右的日志,并且没有完成任务就死了。 我读了几篇文章,其中写到需要使引用变量成为线程安全的,我不知道如何做到这一点。 我的问题是: 该方法是线程安全的吗?我是否在参数或访问变量方面犯了错误

这里是方法

private static Stopwatch timer = new Stopwatch();

public static List<T> PostRequests<T>(string url, string querystring, Request request) where T : IResponse
    {
        try
        {
            if (string.IsNullOrWhiteSpace(querystring))
                querystring = "?apikey=" + AppSettings.APIAccessKey;
            else
                querystring = querystring + "&apikey=" + AppSettings.APIAccessKey;
            var timestamp = string.Format("{0:dd/MM/yyyy HH:mm}", DateTime.UtcNow);

            WsfWebClient client = new WsfWebClient();

            var headers = new WebHeaderCollection();
            headers.Add("timestamp", timestamp);
            headers.Add("Content-Type", "application/json");

            var message = Signer.BuildMessage(url, "POST", HttpUtility.ParseQueryString(querystring), timestamp);
            var signature = Signer.ComputeHash(AppSettings.APISecretKey, message);

            headers.Add("signature", signature);

            client.Headers = headers;                

            var json = request.ToJsonString();

            Logger.Debug(String.Format("SDK: Posting data to the API. JSON: {0}", json));

            timer.Start();
            var response = client.UploadData(AppSettings.APIUrl + url + querystring, "POST", Encoding.Default.GetBytes(json));
            timer.Stop();
            Logger.Info(string.Format("Time Spent for : WSF Call  - {0}", timer.Elapsed.Milliseconds.ToString()));

            return ParseListResponse<T>(Encoding.Default.GetString(response));
        }
        catch (Exception ex)
        {
            Logger.Error("SDK: Post Request to Builder API failed.", ex, typeof(Utilities));
            var responseObject = GetInstance<List<T>>();

            if (responseObject.Count > 0)
            {
                responseObject[0].GenerateError("", "Post Request to Builder API failed.", ex.StackTrace);
            }

            return responseObject;
        }
    }


public class WsfWebClient : WebClient
{
    protected override WebRequest GetWebRequest(Uri uri)
    {
        WebRequest request = base.GetWebRequest(uri);
        // Set timeout for 45 seconds
        request.Timeout = AppSettings.WsfWebClientTimeOut; 
        return request;
    }
}
专用静态秒表计时器=新秒表();
公共静态列表PostRequests(字符串url、字符串querystring、请求请求),其中T:i响应
{
尝试
{
if(string.IsNullOrWhiteSpace(querystring))
querystring=“?apikey=“+AppSettings.APIAccessKey;
其他的
querystring=querystring+“&apikey=“+AppSettings.APIAccessKey;
var timestamp=string.Format(“{0:dd/MM/yyyy HH:MM}”,DateTime.UtcNow);
WsfWebClient客户端=新的WsfWebClient();
var headers=new WebHeaderCollection();
添加(“时间戳”,时间戳);
添加(“内容类型”、“应用程序/json”);
var message=Signer.BuildMessage(url,“POST”,HttpUtility.ParseQueryString(querystring),时间戳);
var signature=Signer.ComputeHash(AppSettings.APISecretKey,message);
标题。添加(“签名”,签名);
client.Headers=Headers;
var json=request.ToJsonString();
Debug(String.Format(“SDK:将数据发布到API.JSON:{0}”,JSON));
timer.Start();
var response=client.UploadData(AppSettings.APIUrl+url+querystring,“POST”,Encoding.Default.GetBytes(json));
timer.Stop();
Info(string.Format(“用于:WSF调用的时间-{0}”,timer.appeased.millizes.ToString());
返回ParseListResponse(Encoding.Default.GetString(response));
}
捕获(例外情况除外)
{
Logger.Error(“SDK:对构建器API的Post请求失败。”,例如,typeof(Utilities));
var responseObject=GetInstance();
如果(responseObject.Count>0)
{
responseObject[0]。GenerateError(“,”对生成器API的Post请求失败“,”ex.StackTrace);
}
返回响应对象;
}
}
公共类WsfWebClient:WebClient
{
受保护的覆盖WebRequest GetWebRequest(Uri)
{
WebRequest=base.GetWebRequest(uri);
//将超时设置为45秒
request.Timeout=AppSettings.WsfWebClientTimeOut;
返回请求;
}
}

请将此值减少为一个值。这里有很多与你的问题无关的东西,这使得你很难找到相关的信息。(我怀疑问题很可能是您向同一主机发出的请求太多,并且它们相互阻塞。如果您不处理响应,这将无助于解决问题,这意味着它将阻塞连接池,直到连接池被垃圾收集。最后,使用
编码。默认
几乎肯定是错误的方法请使用您期望响应的编码。我只对Web服务进行了3次调用,这会产生太大的影响吗?如果连接限制为2,会的,是的……我记不起默认值是什么。(我以为是4,但可能不是。)如果你不处理这些响应,那么你将受到垃圾收集的摆布,因此下一轮请求仍将被这轮请求阻止。因此,首先要做的是在你的
UploadData
调用上放置
using
语句。如果WebClient请求被阻止,它不会创建新的工作进程吗d(对不起,我对此了解有限,我只是澄清一下)