C#(async / await)循环在任务块我的主线程?

时间:2014-06-19 15:20:03

标签: c# multithreading asynchronous async-await

private async Task<PortalODataContext> CallConnection(Connection connection)
    {
        bool cancel = false;
        connection.Connected = true;
        var task = getConnection(connection);

        while (!cancel && !task.IsCompleted)
        {
            Thread.Sleep(100);

            if (connection.Disconected)
            {
                cancel = true;
            }
        }

        return await task;
    }

这是我在主线程上调用的函数,如下所示:

PortalODataContext portalContext = await this.CallConnection(connectionOpen);

我是async的新手,等待所以我只想弄清楚为什么我的任务“CallConnection”会阻止我的主UI线程......你能帮助我吗?

哦,还有GetConnection:

private Task<PortalODataContext> getConnection(Connection connection)
    {            
        return Task.Factory.StartNew(() =>
        {
            try
            {
                var context = connection.ConnectToPortal();
                connection.ListTemplateLib = this.ShellModel.ConnectionManager.GetTemplateLibrarys(connection);
                connection.ListTemplateGrp = this.ShellModel.ConnectionManager.GetTemplateGroups(connection, connection.TemplateLibraryId);
                connection.ListTemplates = this.ShellModel.ConnectionManager.GetTemplates(connection, connection.TemplateGroupId);
                return context;
            }
            catch (Exception)
            {
                throw;
            }
       });

提前致谢

2 个答案:

答案 0 :(得分:5)

尊重Thread.Sleep

async / await将您的方法分成两部分,在await之前和之后。在上半部分,你有一个Thread.Sleep,导致调用者线程冻结。

使用:

private async Task<PortalODataContext> CallConnection(Connection connection)
{
    bool cancel = false;
    connection.Connected = true;
    var task = getConnection(connection);

    while (!cancel && !task.IsCompleted)
    {
        await Task.Delay(100);

        if (connection.Disconected)
        {
            cancel = true;
        }
    }

    return await task;
}

我不完全确定你在这里想要达到的目标。

答案 1 :(得分:0)

当您调用异步任务时,您必须等待结果。

asyncs的好处是你可以在一个方法中运行两个进程,但只能在该方法中运行。 在离开该块之前,必须再次统一两个进程。这使您可以更轻松地运行不同的进程,而无需为所涉及的对象编写委托和锁。

看看here,了解异步方法中会发生什么。那里有一个图表可以帮助您澄清流程。

在您的代码中,您不需要Threed.Sleep。在getConnection返回某些内容之前,CallConnection方法不会返回任何内容。然后你可以继续主线程。

希望能帮助你。