System.Threading.Timer调用回调函数的隐式重复吗?

AGuyInAPlace

我正在使用WPF GUI(使用MVVM)来控制嵌入式设备。到目前为止,该设备仍在开发中,目前无法可靠运行。因此,我创建了以下伪造设备:

interface IConnection
{
    bool IsValid { get; }
    bool Open();
    void Close();
    void Write(string message);
}

class SerialConnection : IConnection
{
    // Not yet implemented
}

class DevConnection : IConnection
{
    Timer _timer;
    Action<string> _callback;

    public bool IsValid {...}

    public DevConnection(Action<string> callback)
    {
        _timer = new Timer(tick, null, Timeout.Infinite, Timeout.Infinite);
        _callback = callback;
    }

    public bool Open() {...}
    public void Close() {...}
    public void Write(string Message) {...}

    private void tick(object args)
    {
        _callback("V01" + ToHex(vol1) + "\n");
        ...    
    }
}


Action<string> _callback;
是使用我的模型来读取连接的有效载荷,并适当地更新其状态的功能

class Model
{
    IConnection _connection;

    public Model()
    {
        _connection = new DevConnection(Message);
    }

    private void Message(string payload)
    {
        ...
        _volume1 = floatValue;
        ...
    }
}

但是,当创建模型时,在调用Model.IConnection.Open()启动计时器之前,我会在其他地方更改一堆属性。每次调用Message()回调时,调试器都会将模型显示为仍处于其原始的构造状态。

1)这里的幕后发生了什么?Threading.Timer是否正在为其计数/滴答执行创建新线程?如果是这样,为什么要创建我的Model类的默认副本?

2)如何解决?我什至尝试给DevConnection我的Model类的副本以直接对其进行操作(不是我想要的架构设置方式),但仍然导致相同的不良行为

不幸的是,我对线程理论只有基本的了解,却不知道如何在C#中实现它。可悲的是,我怀疑此问题是线程管理不当的结果。

亚历克斯

鉴于神秘的“Model班级额外副本”问题已解决。仍然存在如何从计时器计划的回调中安全更新UI的问题。

正如@Frank J所提到的,您的回调将在线程池线程上调用,而仅允许从UI线程的上下文中更新UI元素。这意味着,Message如果直接或间接更新UI元素,则需要将在方法中执行的回调操作编组到UI线程上下文。

下面的代码段显示了一种实现方法。

class Model
{
    private readonly SynchronizationContext _synchronizationContext;
    private readonly IConnection _connection;

    public Model()
    {
         // Capture UI synchronization context.
         // Note: this assumes that Model is constructed on the UI thread.
         _synchronizationContext = SynchronizationContext.Current; 
        _connection = new DevConnection(MessageCallback);
    }

    private void MessageCallback(string payload)
    {
        // schedule UI update on the UI thread.
        _synchronizationContext.Post(
            new SendOrPostCallback(ctx => Message(payload)),
            null);            
    }

    private void Message(string payload)
    {
        ...
        _volume1 = floatValue;
        ...
    }
}

还有一条建议:我认为IConnection应该是这样,IDisposable因为您将不得不在某个地方处置计时器。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

永远不会调用System.Threading.Timer回调

来自分类Dev

再次调用函数时如何保留System.Threading.Timer

来自分类Dev

C#Winforms System.Threading.Timer

来自分类Dev

System.Threading.Timer低级实现

来自分类Dev

System.Threading.Timer停止线程?

来自分类Dev

System.Threading.Timer无法正常工作

来自分类Dev

System.Threading.Timer无法持续工作

来自分类Dev

System.Timers.Timer与System.Threading.Timer的线程安全

来自分类Dev

用System.Threading.Timer替换Thread.Sleep吗?

来自分类Dev

递归调用线程方法(System.Threading)是不好的做法吗?

来自分类Dev

递归调用线程方法(System.Threading)是不好的做法吗?

来自分类Dev

System.Threading回调似乎不太准确

来自分类Dev

System.Threading.Task随机不调用其动作?

来自分类Dev

无法将类型'bool'隐式转换为'system.threading.tasks.task bool'

来自分类Dev

SignalR错误无法将类型'System.Threading.Tasks.Task <object>'隐式转换为'string'

来自分类Dev

无法将类型“ void”隐式转换为“ System.Threading.Tasks.Task”

来自分类Dev

无法将类型'System.Threading.Tasks.Task <String>隐式转换为'string'

来自分类Dev

无法将类型'bool'隐式转换为'System.Threading.Tasks.Task'

来自分类Dev

无法在SignalR中将类型'System.Threading.Tasks.Task <object>'隐式转换为'string'

来自分类Dev

一击式System.Threading.Timer如何自行处置?

来自分类Dev

无法将类型'System.Collections.Generic.List <>'隐式转换为'System.Threading.Tasks.Task <>>

来自分类Dev

如何在同一线程上调用system.threading.timer?

来自分类Dev

为什么我不能在WPF中通过System.Threading.Timer调用使用CapturePhotoToStreamAsync?

来自分类Dev

System.Threading.Tasks.Parallel

来自分类Dev

System.Threading.ThreadStateException OpenFileDialog

来自分类Dev

System.Threading.Tasks.Parallel

来自分类Dev

为什么异步函数返回System.Threading.Tasks.Task`1 [System.String]?

来自分类Dev

System.Threading.Timer与System.Threading.Thread.Sleep分辨率-.NET Timer不使用系统时钟分辨率

来自分类Dev

无法将类型'System.Threading.Tasks.Task <System.Web.Mvc.ActionResult>'隐式转换为'System.Web.Mvc.ActionResult'

Related 相关文章

  1. 1

    永远不会调用System.Threading.Timer回调

  2. 2

    再次调用函数时如何保留System.Threading.Timer

  3. 3

    C#Winforms System.Threading.Timer

  4. 4

    System.Threading.Timer低级实现

  5. 5

    System.Threading.Timer停止线程?

  6. 6

    System.Threading.Timer无法正常工作

  7. 7

    System.Threading.Timer无法持续工作

  8. 8

    System.Timers.Timer与System.Threading.Timer的线程安全

  9. 9

    用System.Threading.Timer替换Thread.Sleep吗?

  10. 10

    递归调用线程方法(System.Threading)是不好的做法吗?

  11. 11

    递归调用线程方法(System.Threading)是不好的做法吗?

  12. 12

    System.Threading回调似乎不太准确

  13. 13

    System.Threading.Task随机不调用其动作?

  14. 14

    无法将类型'bool'隐式转换为'system.threading.tasks.task bool'

  15. 15

    SignalR错误无法将类型'System.Threading.Tasks.Task <object>'隐式转换为'string'

  16. 16

    无法将类型“ void”隐式转换为“ System.Threading.Tasks.Task”

  17. 17

    无法将类型'System.Threading.Tasks.Task <String>隐式转换为'string'

  18. 18

    无法将类型'bool'隐式转换为'System.Threading.Tasks.Task'

  19. 19

    无法在SignalR中将类型'System.Threading.Tasks.Task <object>'隐式转换为'string'

  20. 20

    一击式System.Threading.Timer如何自行处置?

  21. 21

    无法将类型'System.Collections.Generic.List <>'隐式转换为'System.Threading.Tasks.Task <>>

  22. 22

    如何在同一线程上调用system.threading.timer?

  23. 23

    为什么我不能在WPF中通过System.Threading.Timer调用使用CapturePhotoToStreamAsync?

  24. 24

    System.Threading.Tasks.Parallel

  25. 25

    System.Threading.ThreadStateException OpenFileDialog

  26. 26

    System.Threading.Tasks.Parallel

  27. 27

    为什么异步函数返回System.Threading.Tasks.Task`1 [System.String]?

  28. 28

    System.Threading.Timer与System.Threading.Thread.Sleep分辨率-.NET Timer不使用系统时钟分辨率

  29. 29

    无法将类型'System.Threading.Tasks.Task <System.Web.Mvc.ActionResult>'隐式转换为'System.Web.Mvc.ActionResult'

热门标签

归档