首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在非UI线程Silverlight5浏览器应用程序中创建UserControl

在非UI线程Silverlight5浏览器应用程序中创建UserControl
EN

Stack Overflow用户
提问于 2016-09-22 22:19:12
回答 1查看 221关注 0票数 11

我有一个Silverlight 5浏览器应用程序。

有一个类

代码语言:javascript
复制
public class ActivityControl:UserControl {

    public void LoadSubControls() {
        //Creates Other UserControls, does calculations and is very slow..No refactoring..
    }
}

我需要创建该类的多个实例,并在运行时调用方法LoadSubControls。

代码语言:javascript
复制
public class BasicContainer:UserControl  {

    public void CreateMultipleActivityControls() {

        for (int i = 0; i < 1000; i++) {

            ActivityControl c = new ActivityControl();  ====> I need to call this in a different thread but causes Invalid Cross Thread Exception

            c.LoadSubControls();
        }
    }
}

有没有办法创建多个UI线程,以避免无效的跨线程异常?

出于性能原因,我需要多线程,因为方法调用非常慢,并且UI冻结。

有没有办法在Silverlight中调用方法SetSyncronizationContext (即SecurityCritical)?

EN

回答 1

Stack Overflow用户

发布于 2016-09-27 08:22:15

在UI线程上创建这些控件是不可避免的,但是您可以利用任务并行库(TPL)中的System.Threading.Tasks.Task来允许异步操作。

我已经能够在silverlight 5中使用这样的结构来做类似的事情。通过查看Caliburn.Micro的源代码得到了最初的想法。

以下是适用于您需要的内容的子集。

代码语言:javascript
复制
public interface IPlatformProvider {
    /// <summary>
    ///  Executes the action on the UI thread asynchronously.
    /// </summary>
    /// <param name = "action">The action to execute.</param>
    System.Threading.Tasks.Task OnUIThreadAsync(Action action);    
}

下面是实现。

代码语言:javascript
复制
/// <summary>
/// A <see cref="IPlatformProvider"/> implementation for the XAML platfrom (Silverlight).
/// </summary>
public class XamlPlatformProvider : IPlatformProvider {
    private Dispatcher dispatcher;

    public XamlPlatformProvider() {
       dispatcher = System.Windows.Deployment.Current.Dispatcher;
    }

    private void validateDispatcher() {
        if (dispatcher == null)
            throw new InvalidOperationException("Not initialized with dispatcher.");
    }

    /// <summary>
    ///  Executes the action on the UI thread asynchronously.
    /// </summary>
    /// <param name = "action">The action to execute.</param>
    public Task OnUIThreadAsync(System.Action action) {
        validateDispatcher();
        var taskSource = new TaskCompletionSource<object>();
        System.Action method = () => {
            try {
                action();
                taskSource.SetResult(null);
            } catch (Exception ex) {
                taskSource.SetException(ex);
            }
        };
        dispatcher.BeginInvoke(method);
        return taskSource.Task;
    }
}

您可以沿着构造器DI路由传递提供程序,也可以使用如下所示的静态定位器模式。

代码语言:javascript
复制
/// <summary>
/// Access the current <see cref="IPlatformProvider"/>.
/// </summary>
public static class PlatformProvider {
    private static IPlatformProvider current = new XamlPlatformProvider();

    /// <summary>
    /// Gets or sets the current <see cref="IPlatformProvider"/>.
    /// </summary>
    public static IPlatformProvider Current {
        get { return current; }
        set { current = value; }
    }
}

现在,您应该能够在不阻塞主线程和冻结UI的情况下进行调用

代码语言:javascript
复制
public class BasicContainer : UserControl {
    public async Task CreateMultipleActivityControls() {
        var platform = PlatformProvider.Current;
        for (var i = 0; i < 1000; i++) {
            await platform.OnUIThreadAsync(() => {    
                var c = new ActivityControl();     
                c.LoadSubControls();
            });    
        }
    }
}

如果对dispatcher进行多次调用会导致任何性能问题,则可以将整个流程移到一个异步调用中。

代码语言:javascript
复制
public class BasicContainer : UserControl {
    public async Task CreateMultipleActivityControls() {
        var platform = PlatformProvider.Current;
        await platform.OnUIThreadAsync(() => {
            for (var i = 0; i < 1000; i++) {                    
                var c = new ActivityControl();     
                c.LoadSubControls();
            }    
        });
    }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39641615

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档