[英]How to implement this multi-threading scenario in c#
我想做這樣的事情:
function void DoSomething(string path){
try {
DownloadDataFromWebSite(path)
}catch(OtherUserLoggedInUsingSameAcountException ex){
If (I am the first thread that get here){
Login();
}else{
Wait for the first thread to finish Login();
}
DownloadDataFromWebSite(path);
}
}
我有一個這樣的收藏集:
APathCollection.AsParallel().ForAll(DoSomething)
請幫助我,如何實現此模式? 可能嗎?
PS:我已經省略了錯誤計數器,請假設它不會進入無限循環。
更新:我已更新代碼以反映我對@IPValverde請求的實際操作。
好的,您提供了有關您的方案的更多信息。 我認為您可以創建第二個鎖,以指示您的線程之一是否正在登錄。
這是一個片段:
public class Program
{
public static void Main()
{
new Program().Execute();
}
public void Execute()
{
// lock objects
this.fixErrorLock = new object();
this.isLoggingInLock = new object();
var objectsToIterate = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
objectsToIterate.AsParallel().ForAll(this.DoWork);
}
private object isLoggingInLock;
private object fixErrorLock;
private bool isLoggingIn;
public bool IsThereAnyThreadLoggingIn()
{
lock (this.isLoggingInLock)
{
// If no thread is logging-in, the one who asked is going to log-in
if (!this.isLoggingIn)
this.isLoggingIn = true;
return this.isLoggingIn;
}
}
public void DoWork(int myParam)
{
try
{
if (myParam % 4 == 0)
throw new Exception();
}
catch (Exception ex)
{
// Is the equivalent of 'is the first thread to hit here?'
bool canLogIn = this.IsThereAnyThreadLoggingIn();
// Every thread with error will stop here
lock (fixErrorLock)
{
// But only the first one will do the login process again
if (canLogIn)
{
// Inside the login method the variable responsible for the 'isFirstThread' is restored to false
this.LogIn();
}
}
this.DoWork(myParam-1);
}
}
public void LogIn()
{
Thread.Sleep(100);
lock (this.isLoggingInLock)
{
// The login is done
this.isLoggingIn = false;
}
}
}
您可以看到此示例在此處運行: https : //dotnetfiddle.net/SOXxO9
在談論線程安全時,重要的是資源。
因此,請先閱讀有關鎖的內容 ,尤其是有關關鍵部分的內容。
然后,在FixparticularException
方法中為每個“邏輯”資源創建一個鎖,這應該沒問題。 如果您提供一些細節,我可以為您更明確地編寫代碼,以下是要點:
private bool _IsFixed;
public void DoSomething(int x)
{
try
{
DoWork(x)
}
catch (ParticularException pex)
{
FixParticularException(pex);
}
DoSomething(x);
}
private void FixParticularException (ParticularException pex)
{
lock (_resource1Lock)
{
if (_IsFixed)
return;
// fix it
_IsFixed = true;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.