调用事件是跨线程的吗?

用户名

我正在上一个看起来像这样的课:

public class MatchmakingService  {
    private bool working;
    private List<MatchmakingUser> matchmakingUsers;
    // ...

    public MatchmakingService()
    {
        matchmakingUsers = new List<MatchmakingUser>();
    }

    public void StartService () {
        var thread = new Thread(this.MatchmakingWork);
        working = true;
        thread.Start();
    }

    void MatchmakingWork () {
        while (working)
        {
            // some work, match found!
            {
                  if(onMatchFound != null)
                      onMatchFound(this, new NewMatchEventArgs(matchmakingUsers[i], matchmakingUsers[j]);
            }
            Thread.Sleep(1000);
        }
    }
}

通常,当找到匹配项时,我会在onMatchFound上触发一个事件并将其命名为一天,但是由于服务的线程不同,并且该事件的订阅者将位于不同的线程上-如何处理?我读过这样做是不安全的,如果是真的,那我有什么选择?

注意:我不使用WinForms,所以没有Control的Invoke恶作剧。

杰罗恩·范·朗根(Jeroen van Langen)

最简单的方法是创建队列。有多种实现队列的方法。我会在MatchmakingService

使用队列存储匹配项,其他线程必须调用该RaiseEvents()方法来处理队列。这意味着,另一个线程应该有一个Timer / DispatcherTimer /,同时有睡眠等。

例子:

public class MatchmakingService
{
    private bool working;
    private List<MatchmakingUser> matchmakingUsers;
    // ...

    // the queue
    private List<NewMatchEventArgs> _queue = new List<NewMatchEventArgs>();


    public MatchmakingService()
    {
        matchmakingUsers = new List<MatchmakingUser>();
    }

    public void StartService()
    {
        var thread = new Thread(this.MatchmakingWork);
        working = true;
        thread.Start();
    }

    void MatchmakingWork()
    {
        while (working)
        {
            // some work, match found!
            {
                lock (_queue)
                    _queue.Add(new NewMatchEventArgs(matchmakingUsers[1], matchmakingUsers[2]));
            }
            Thread.Sleep(1000);
        }
    }

    public void RaiseEvents()
    {
        NewMatchEventArgs[] copyOfQueue;

        // create a copy (bulk action)
        lock (_queue)
        {
            copyOfQueue = _queue.ToArray();
            _queue.Clear();
        }

        // handle the items
        if (onMatchFound != null)
            foreach (var item in copyOfQueue)
                onMatchFound(this, item); // indices are examples

    }

    public event EventHandler<NewMatchEventArgs> onMatchFound;

}

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

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

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

以并行方式执行线程,但以相同顺序调用事件

来自分类Dev

如何调用事件?

来自分类Dev

使用事件发射器和服务进行跨组件通信的角度异步调用

来自分类Dev

C#调用事件

来自分类Dev

从主函数调用事件

来自分类Dev

通过showInputDialog调用事件

来自分类Dev

当操作执行到Task时,如何通过UI线程调用事件处理程序?(C#)

来自分类Dev

状态机中的阻塞系统调用是调用事件吗

来自分类Dev

调用方法后的调用事件

来自分类Dev

调用方法后的调用事件

来自分类Dev

在调用事件时使用Thread.Sleep,但不起作用吗?(C#)

来自分类Dev

调用事件,h(args)与EventName?.Invoke()

来自分类Dev

在Bootstrap面板上调用事件展开

来自分类Dev

用JavaScript创建和调用事件

来自分类Dev

一次通用事件调用?

来自分类Dev

检查哪个对象调用事件方法

来自分类Dev

直接调用事件处理程序

来自分类Dev

哪个UserControl调用事件MouseEnter?

来自分类Dev

如何获取调用事件的BrowserWindow实例?

来自分类Dev

在函数C#中调用事件

来自分类Dev

取消订阅后调用事件

来自分类Dev

在UI上调用事件方法

来自分类Dev

检查哪个对象调用事件方法

来自分类Dev

jQuery滑块避免过快调用事件

来自分类Dev

未调用事件侦听器

来自分类Dev

调用事件,h(args)与EventName?.Invoke()

来自分类Dev

直接调用事件处理程序

来自分类Dev

ClearInterval 删除与否调用事件 JS

来自分类Dev

实现跨线程调用检查