在.NET中阻塞线程

3
我有一个类,其中仅包含静态方法和属性。我正在调用该类上的异步方法"Load",该方法向Web服务请求一块数据,然后触发一个事件来执行返回方法"LoadCompleted"。我不知道调用需要多长时间(即调用"Load"方法,然后调用"LoadCompleted"之间的时间差)。
我想阻止应用程序继续进行,直到回调方法被触发(因为应用程序将尝试从此类获取内容,但在"LoadComplete"方法设置数据之前,该类未被填充)。我该如何做?

6
所以您正在使用一个需要阻塞所有操作直到完成的异步方法...?我肯定误解了您的意思,对吗? - djdd87
你可能会这样想,但不,你是正确的。由于它正在调用 Web 服务,因此必须是异步的,所以我别无选择。 - Ben
为什么只是调用 Web 服务就需要异步操作呢?我只熟悉 Silverlight 客户端中有这种限制。 - Kirk Woll
我正在使用SilverLight客户端。 - Ben
5
听起来你的做法完全不对。为什么不能在类加载时显示等待对话框?当LoadComplete触发时,关闭等待对话框并继续进行。用户更喜欢看到进度指示器,而不是看到整个用户界面冻结。我认为你正在“修复”错误的问题。 - djdd87
3个回答

6

极力避免阻塞主UI线程。

我会使用Silverlight Toolkit中的BusyIndicator控件:

<UserControl x:Class="StackoverflowSpikes.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit">

    <toolkit:BusyIndicator x:Name="busyInd" >
        <Grid x:Name="LayoutRoot">
          <!-- The rest of your content -->
        </Grid>
    </toolkit:BusyIndicator>

</UserControl>

在调用 Load 之前,请使用以下内容:-
busyInd.IsBusy = true;

然后在LoadComplete中使用:

busyInd.IsBusy = false;

这将锁定UI上的用户输入,而不会阻塞主线程,并向用户提供一些反馈,告诉他们为什么现在无法单击任何内容。您可以使用BustContent属性提供自己的忙碌消息内容。当然,如果您不喜欢它的外观,可以根据自己的喜好进行样式设置。
如果您想要完全采用MVVM模式,可以将IsBusy属性绑定到表示VM当前不希望有任何更改的VM属性。

2

您可以使用ManualResetEvent类来阻止主线程。只需调用WaitOne方法来阻塞,当异步Web请求完成时调用Set方法来解除阻塞。但请注意,如果阻塞主UI线程,整个应用程序将变得完全无响应。


1
您可以考虑在开始时将 UI 控件设置为禁用状态。在加载完成后,您可以显示数据,然后启用 UI 控件。使用此方法不需要线程阻塞。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接