We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
single session插件无法正常运作
**描述问题：**

如果在另一个 `run_preprocessor` 中 `raise IgnoredException` , 会导致 `single session` 插件无法正确执行删除操作 , 导致之后的 `matcher` 被无情 `IgnoredException(Another matcher running)` 掉

**如何复现？**

用 `run_preprocessor` 装饰一个函数并抛出 `IgnoredException` , 然后尝试触发另一个 `matcher` , 得到 log "matcher running is cancelled"

**期望的结果**

matcher 正常运行

**环境信息：**

 - OS: linux
 - Python Version: 3.10
 - Nonebot Version: 2b1

**协议端信息：**

 - 协议端: gocq
 - 协议端版本: b8f2

**截图或日志**

If applicable, add screenshots to help explain your problem.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `nonebot/plugins/single_session.py`
Content:
```
1 from typing import Dict
2 
3 from nonebot.adapters import Event
4 from nonebot.message import (
5     IgnoredException,
6     run_preprocessor,
7     run_postprocessor,
8 )
9 
10 _running_matcher: Dict[str, int] = {}
11 
12 
13 @run_preprocessor
14 async def preprocess(event: Event):
15     try:
16         session_id = event.get_session_id()
17     except Exception:
18         return
19     current_event_id = id(event)
20     event_id = _running_matcher.get(session_id, None)
21     if event_id and event_id != current_event_id:
22         raise IgnoredException("Another matcher running")
23 
24     _running_matcher[session_id] = current_event_id
25 
26 
27 @run_postprocessor
28 async def postprocess(event: Event):
29     try:
30         session_id = event.get_session_id()
31     except Exception:
32         return
33     if session_id in _running_matcher:
34         del _running_matcher[session_id]
35
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/nonebot/plugins/single_session.py b/nonebot/plugins/single_session.py
--- a/nonebot/plugins/single_session.py
+++ b/nonebot/plugins/single_session.py
@@ -1,34 +1,31 @@
-from typing import Dict
+from typing import Dict, Generator
 
 from nonebot.adapters import Event
-from nonebot.message import (
-    IgnoredException,
-    run_preprocessor,
-    run_postprocessor,
-)
+from nonebot.params import Depends
+from nonebot.message import IgnoredException, event_preprocessor
 
 _running_matcher: Dict[str, int] = {}
 
 
-@run_preprocessor
-async def preprocess(event: Event):
+async def matcher_mutex(event: Event) -> Generator[bool, None, None]:
+    result = False
     try:
         session_id = event.get_session_id()
     except Exception:
-        return
-    current_event_id = id(event)
-    event_id = _running_matcher.get(session_id, None)
-    if event_id and event_id != current_event_id:
-        raise IgnoredException("Another matcher running")
-
-    _running_matcher[session_id] = current_event_id
+        yield result
+    else:
+        current_event_id = id(event)
+        event_id = _running_matcher.get(session_id, None)
+        if event_id:
+            result = event_id != current_event_id
+        else:
+            _running_matcher[session_id] = current_event_id
+        yield result
+        if not result:
+            del _running_matcher[session_id]
 
 
-@run_postprocessor
-async def postprocess(event: Event):
-    try:
-        session_id = event.get_session_id()
-    except Exception:
-        return
-    if session_id in _running_matcher:
-        del _running_matcher[session_id]
+@event_preprocessor
+async def preprocess(mutex: bool = Depends(matcher_mutex)):
+    if mutex:
+        raise IgnoredException("Another matcher running")

{"golden_diff": "diff --git a/nonebot/plugins/single_session.py b/nonebot/plugins/single_session.py\n--- a/nonebot/plugins/single_session.py\n+++ b/nonebot/plugins/single_session.py\n@@ -1,34 +1,31 @@\n-from typing import Dict\n+from typing import Dict, Generator\n \n from nonebot.adapters import Event\n-from nonebot.message import (\n-    IgnoredException,\n-    run_preprocessor,\n-    run_postprocessor,\n-)\n+from nonebot.params import Depends\n+from nonebot.message import IgnoredException, event_preprocessor\n \n _running_matcher: Dict[str, int] = {}\n \n \n-@run_preprocessor\n-async def preprocess(event: Event):\n+async def matcher_mutex(event: Event) -> Generator[bool, None, None]:\n+    result = False\n     try:\n         session_id = event.get_session_id()\n     except Exception:\n-        return\n-    current_event_id = id(event)\n-    event_id = _running_matcher.get(session_id, None)\n-    if event_id and event_id != current_event_id:\n-        raise IgnoredException(\"Another matcher running\")\n-\n-    _running_matcher[session_id] = current_event_id\n+        yield result\n+    else:\n+        current_event_id = id(event)\n+        event_id = _running_matcher.get(session_id, None)\n+        if event_id:\n+            result = event_id != current_event_id\n+        else:\n+            _running_matcher[session_id] = current_event_id\n+        yield result\n+        if not result:\n+            del _running_matcher[session_id]\n \n \n-@run_postprocessor\n-async def postprocess(event: Event):\n-    try:\n-        session_id = event.get_session_id()\n-    except Exception:\n-        return\n-    if session_id in _running_matcher:\n-        del _running_matcher[session_id]\n+@event_preprocessor\n+async def preprocess(mutex: bool = Depends(matcher_mutex)):\n+    if mutex:\n+        raise IgnoredException(\"Another matcher running\")\n", "issue": "single session\u63d2\u4ef6\u65e0\u6cd5\u6b63\u5e38\u8fd0\u4f5c\n**\u63cf\u8ff0\u95ee\u9898\uff1a**\r\n\r\n\u5982\u679c\u5728\u53e6\u4e00\u4e2a `run_preprocessor` \u4e2d `raise IgnoredException` , \u4f1a\u5bfc\u81f4 `single session` \u63d2\u4ef6\u65e0\u6cd5\u6b63\u786e\u6267\u884c\u5220\u9664\u64cd\u4f5c , \u5bfc\u81f4\u4e4b\u540e\u7684 `matcher` \u88ab\u65e0\u60c5 `IgnoredException(Another matcher running)` \u6389\r\n\r\n**\u5982\u4f55\u590d\u73b0\uff1f**\r\n\r\n\u7528 `run_preprocessor` \u88c5\u9970\u4e00\u4e2a\u51fd\u6570\u5e76\u629b\u51fa `IgnoredException` , \u7136\u540e\u5c1d\u8bd5\u89e6\u53d1\u53e6\u4e00\u4e2a `matcher` , \u5f97\u5230 log \"matcher running is cancelled\"\r\n\r\n**\u671f\u671b\u7684\u7ed3\u679c**\r\n\r\nmatcher \u6b63\u5e38\u8fd0\u884c\r\n\r\n**\u73af\u5883\u4fe1\u606f\uff1a**\r\n\r\n - OS: linux\r\n - Python Version: 3.10\r\n - Nonebot Version: 2b1\r\n\r\n**\u534f\u8bae\u7aef\u4fe1\u606f\uff1a**\r\n\r\n - \u534f\u8bae\u7aef: gocq\r\n - \u534f\u8bae\u7aef\u7248\u672c: b8f2\r\n\r\n**\u622a\u56fe\u6216\u65e5\u5fd7**\r\n\r\nIf applicable, add screenshots to help explain your problem.\r\n\n", "before_files": [{"content": "from typing import Dict\n\nfrom nonebot.adapters import Event\nfrom nonebot.message import (\n    IgnoredException,\n    run_preprocessor,\n    run_postprocessor,\n)\n\n_running_matcher: Dict[str, int] = {}\n\n\n@run_preprocessor\nasync def preprocess(event: Event):\n    try:\n        session_id = event.get_session_id()\n    except Exception:\n        return\n    current_event_id = id(event)\n    event_id = _running_matcher.get(session_id, None)\n    if event_id and event_id != current_event_id:\n        raise IgnoredException(\"Another matcher running\")\n\n    _running_matcher[session_id] = current_event_id\n\n\n@run_postprocessor\nasync def postprocess(event: Event):\n    try:\n        session_id = event.get_session_id()\n    except Exception:\n        return\n    if session_id in _running_matcher:\n        del _running_matcher[session_id]\n", "path": "nonebot/plugins/single_session.py"}], "after_files": [{"content": "from typing import Dict, Generator\n\nfrom nonebot.adapters import Event\nfrom nonebot.params import Depends\nfrom nonebot.message import IgnoredException, event_preprocessor\n\n_running_matcher: Dict[str, int] = {}\n\n\nasync def matcher_mutex(event: Event) -> Generator[bool, None, None]:\n    result = False\n    try:\n        session_id = event.get_session_id()\n    except Exception:\n        yield result\n    else:\n        current_event_id = id(event)\n        event_id = _running_matcher.get(session_id, None)\n        if event_id:\n            result = event_id != current_event_id\n        else:\n            _running_matcher[session_id] = current_event_id\n        yield result\n        if not result:\n            del _running_matcher[session_id]\n\n\n@event_preprocessor\nasync def preprocess(mutex: bool = Depends(matcher_mutex)):\n    if mutex:\n        raise IgnoredException(\"Another matcher running\")\n", "path": "nonebot/plugins/single_session.py"}]}