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