簡體   English   中英

如何在C#中實現此多線程方案

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM