簡體   English   中英

C#:如何從循環外停止執行 for 循環?

[英]C#: how can i stop the execution of for loop from outside of the loop?

我有 class 使用固定緩沖區大小從大文件(1GB)讀取數據並將其寫入數組。 我想讓用戶隨時取消該過程。 我如何從循環外部停止循環。(我認為使用事件是個好主意,但不知道該怎么做)

注意:我有一個表格可以發送取消請求。

for (int i = 0; i < fileContent.Length; i++)
                    {
                        try
                        {
                            fileContent[i] = br.ReadInt16();
                        }
                        catch (EndOfStreamException)
                        {
                            loadflag = 1;
                            contentSize = i;
                            break;
                        }
                    }
                    for (int k = 0; k < contentSize; k += ReSampleRate)
                    {
                        try
                        {
                            convertedData[(count * fileContent.Length / ReSampleRate) + j] = fileContent[k];
                            j++;
                        }
                        catch (IndexOutOfRangeException)
                        {
                            MessageBox.Show("could not load the file completely");
                            goto lable;
                        }
                        catch
                        {
                            MessageBox.Show("something went wrong");
                        }
                    }



                    if (loadflag == 1)
                    {
                        break;
                    }

                }


使您的方法采用CancellationToken 更改您的循環,使其在每次迭代時調用cancellationToken.ThrowIfCancellationRequested() 確保您的調用者捕捉到產生的OperationCancelledException 表單應該創建一個CancellationTokenSource ,它帶有一個可以提供給您的方法的 Token 屬性,以及一個可以由您的表單調用的取消方法。

請注意,您的方法需要在后台線程上運行才能使所有這些工作,通常使用Task.Run ,但這需要您將消息框和任何其他更新 UI 的代碼移到要取消的方法之外. 如果您有一個主要等待 IO 完成的異步方法,則可能是一個例外。

例子:

private CancellationTokenSource cts = new CancellationTokenSource();;
public async void OnButtonPress(){
    try{
        cts = new CancellationTokenSource();
        await Task.Run(() => OnBackgroundThread(cts.Token));
        void OnBackgroundThread(CancellationToken cancel){
            foreach(var item in MyItemsToProcess){
                cancel.ThrowIfCancellationRequested();
                // Process item
            }
        }
       catch(OperationCancelledException){
           // do nothing
       }
       // Handle other errors
    }
}
public void OnCancelPress(){
    cts.Cancel();
}

另一種變體是檢查cancellationToken.IsCancellationRequested屬性並正常返回。 但這使得調用者無法確定循環是否完成,充其量只能檢查令牌是否被取消。

如果您正在尋找某種方法來取消循環而不對其進行任何更改,那么您就不走運了。 沒有好的方法可以非合作地中止正在運行的線程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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