【问题标题】:C# + WinRT + Monogame threading for network (Azure Mobile Service) operations用于网络(Azure 移动服务)操作的 C# + WinRT + Monogame 线程
【发布时间】:2013-09-29 18:13:46
【问题描述】:

我的应用程序中有一个循环,它按以下方式循环遍历一组实体

foreach(var entity in mEntities)
{
    entity.Update();
}

其中一些实体维护一个网络组件,该组件将调用 Azure 移动服务,以便将其状态更新到服务器。下面是一个例子:

public class TestEntity {
    public int Index;
    public int PropertyValue;

    public async void Update()
    {
        Task.Run(() => {
            MyAzureMobileServiceClient.Update(Index, PropertyValue);
        });
    }
}

UI 渲染由 Monogame 以更传统的游戏循环方式完成。虽然我不知道它的内部工作原理,但我相当确定它没有真正的单独线程来完成这项工作。实际上,这显示为每次调用此更新时 UI 都会冻结。

我希望能够在后台“顺利”运行它。在旧的 Windows 模型中,这可以通过启动一个处理它的新线程来轻松完成,但我对 WinRT 中的线程处理不够了解,无法理解我的方法有什么问题。

有什么想法吗?

[更新] 我也试过这个:

Task.Factory.StartNew(async () =>
{
    while(true) {
        await Task.Delay(1000);
        MyAzureMobileServiceClient.Update(Index, PropertyValue);
    }
});

每隔 1 秒,我就会像以前一样进行一次小冻结。

[更新 2] 我尝试了这个。我用标准的 HTTP 请求替换了 Azure 移动服务客户端调用,它运行得非常好;没有小冻结。当然它还没有到后端,但至少我可以通过手动完成整个事情来解决这个问题。但是,宁愿不这样做。

[更新 3] 这越来越奇怪了。我意识到我简化了这个问题中的代码,以使其在上下文中保持一致。然而,这似乎已经消除了问题的真正根源。我尝试了以下方法:

  1. 我创建了一个 HTTP 请求并手动创建了该请求,在 Task.Run() 中调用它,它运行良好,没有延迟。
  2. 我直接调用 Azure 移动服务客户端更新,没有延迟。

所以这让我找到了问题所在。我基本上有一个 Azure 移动服务的包装类。真正走的路大概是这样的:

CommunicationClient.UpdateAsync(myObject);

public Task UpdateAsync(MyObjectType obj)
{
    var table = mMobileServiceClient.GetTable<MyObjectType>();
    return table.UpdateAsync(obj);
}

这会导致延迟,但如果我这样做而不是它,它不会有任何延迟:

var client = CommunicationClient.MobileServiceClient;
var table = client.GetTable<MyObjectType>();
table.UpdateAsync(obj);

太好了……我可能应该重构整个问题。它越来越干了。

【问题讨论】:

  • 在这里很难看出所有活动部件是如何组合在一起的。是数据请求导致暂停还是使用获取的数据更新 UI?如果是后者,那就是更大的挑战了。
  • 是后者,这将使其成为挑战。基本上我目前什至不更新用户界面,而只是发送一个请求。我的原始帖子不准确,因为我将 Azure 移动服务后端用于我的应用程序。实际上,这意味着发送 HTTP 请求并获得响应。也许我的代码中某处存在一个愚蠢的用户错误,导致我的更新线程等待响应。我可能会更深入地研究 Monogame 如何处理渲染。如果有帮助,则从 Monogame 更新循环中调用 Update()。
  • 我应该补充一点,我正在等待的响应仅仅是“200 OK”或“### Error”。不需要实际数据,而且我对返回的内容并不真正感兴趣。此外,发送的数据是一个简单的小型“jsonized”结构,其中包含几个字符串和几个整数。也就是说移动的数据量真的很小。
  • 您可以查看调度程序是否将您的任务内联到同一个线程而不是创建一个新线程。 C# 中的默认行为是允许这样做。您可以通过将您的任务标记为长时间运行来暗示它不应该。即:Task.Factory.StartNew(Action, TaskCreationOptions.LongRunning);

标签: c# multithreading wcf windows-runtime monogame


【解决方案1】:

我有一个关于如何在后台线程上运行的问题,他们建议我使用 ThreadPool,所以我建议你看看我的问题和答案,也许你可以了解一些事情并让它继续工作你的结局。

Create Backgroundthread Monogame

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-01
    • 2012-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多