多个线程调用相同的函数。一旦条件成立,删除所有线程

时间:2017-09-08 20:10:34

标签: c# multithreading

我目前正在创建多个Threads来调用一个函数来检查while loop内的语句是否为真。

我的问题:

我创建了10个不同的线程,它们同时运行相同的功能,到目前为止工作正常。但是一旦bool isAviable变为true,else check中的其他代码将被执行10次,因为有10个线程正在运行。

一旦bool isAviable变为true,我能以某种方式停止其他线程并继续使用1个线程吗?

示例如何启动线程:

for(int i = 0; i < 10; i++)
{
    new Thread(new ThreadStart(function)) { IsBackground = true }.Start();
}

被调用的函数示例:

private void function()
{
    try
    {
        bool isAviable = false;

        while (isAviable == false)
        {
            isAviable = checkFunction(bunifuMetroTextbox3.Text);

            if (isAviable == false)
            {
                base.Invoke(new Action(method_5));
            }
            else
            {
                // Ececute other function code which should only be executed by one thread..
            }
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

示例checkFunction:

private bool checkFunction(string handle)
{
    bool aviable = false;

    while (!aviable)
    {
        using (WebClient client = new WebClient())
        {
            try
            {
                if (client.DownloadString("http://url.com/script.php?user=" + handle).Contains("No users found"))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch(WebException ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }

    return false;
}

1 个答案:

答案 0 :(得分:2)

因此,由于您正在进行的工作是IO绑定,而不是CPU绑定,因此您不应该创建新线程。你应该只是为你的IO使用异步方法,以保持你的UI响应,而不是创建只是花费他们所有时间坐在什么都不做的线程。这是对您的方法进行的一项简单的更改,可以检查给定用户是否可用:

private async Task<bool> IsUserAvaliable(string handle)
{
    while (true)
    {
        using (HttpClient client = new HttpClient())
        {
            try
            {
                string content = await client.GetStringAsync("http://url.com/script.php?user=" + handle);
                return content.Contains("No users found");
            }
            catch (WebException ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
}

接下来,对于调用方法,它从根本上简化了代码,使其简单地表示确定用户何时可用,而不考虑在以下情况下需要执行的操作:

private async Task CheckUntilUserIsAvaliable()
{
    //presumably bunifuMetroTextbox3 shouldn't be hard coded, but instead passed in, but it's unclear
    while (!await IsUserAvaliable(bunifuMetroTextbox3.Text))  
    {
        method_5();
        await Task.Delay(1000); //adjust as appropriate for what the poll time should be
    }
}

接下来,我们可以创建一个方法来调用CheckUntilUserIsAvaliable 10次不同的时间,我们可以使用WhenAny来确定其中任何一个完成的时间。在其中一个完成后,我们可以在第一个用户可用时完成任何需要完成的工作:

private async Task CheckUntilOneOfTheUsersIsAvaliable()
{
    await Task.WhenAny(Enumerable.Range(0, 10)
        .Select(i => CheckUntilUserIsAvaliable()));
    //Work to be done when any one of the checking operations has indicated that it's avalaible
}