rksoftware

Visual Studio とか C# とかが好きです

PC のバッテリーが持たない理由と対策 (かもしれない)

以前より、PC のバッテリーの持ちが悪く、2 時間すら持たない状況に悩んでいました。
スペック的には、8 時間くらい持つことになっていてバッテリーも劣化しておらず。

rksoftware.hatenablog.com

■ 結論 - プライバシーフィルターと日光

プライバシーフィルター (のぞき見防止フィルター) と野外使用のために、画面を明るくして使っていたのが理由かもしれません。
屋内かつフィルターを外すと画面の明るさを落としても画面がちゃんと見えたので、その状況で使っていると驚くほどにバッテリーが減らない。

# ■ 課題

完璧な作戦なのですが、プライバシーフィルターは必須ですし、野外でも使いたいのでちょっと常用できる対策ではない点を除けば、です。

C# 13 ReadOnlySet

.NET 9 のプレビュー版で ReadOnlySet 書けるようになっています。 github.com

Set を安全に使うのに役に立つでしょう。

■ allows ref struct

こんな感じで、読み取り専用の Set を作れるようです。
次の例では出力が 12 ではなく 123 であることもポイントです。

System.Collections.Generic.HashSet<char> hashSet = new ("12");
System.Collections.ObjectModel.ReadOnlySet<char> readOnlySet = new(hashSet);
hashSet.Add('3');   // これはできる
// readOnlySet.Add('4');   // CS1061  'ReadOnlySet<char>' に 'Add' の定義が含まれておらず、型 'ReadOnlySet<char>' の最初の引数を受け付けるアクセス可能な拡張メソッド 'Add' が見つかりませんでした。using ディレクティブまたはアセンブリ参照が不足していないことを確認してください

foreach(char c in readOnlySet) Console.Write(c);    // 123

■ 備えよう

.NET 9。備えよう。

C# 13 allows ref struct

.NET 9 のプレビュー版で allows ref struct 書けるようになっています。 github.com

パフォーマンスに厳しい用途で使われるライブラリなどで役に立つでしょう。

■ allows ref struct

こんな感じで、Span なんかをジェネリクスで受け入れられるようになります。

var span = "Saitama".AsSpan();
Method1("Saitama"); // これはできる
Method2("Saitama"); // これはできる

Method1(span);  // これはできるようになった
//Method2(span);  // これはできない  CS9244  'ReadOnlySpan<char>' 型は、ジェネリック型またはメソッド 'Method2<T>(T)' のパラメーター 'T' として使用するためには、ref 構造体または ref 構造体を許容する型パラメーターにすることはできません。

static void Method1<T>(T arg)  where T : allows ref struct { }
static void Method2<T>(T arg) { }

■ 試すために

.csproj ファイルを編集する必要があります。

<LangVersion>preview</LangVersion>

を追加します。これを追加しないと次のエラーになります。

CS8652   機能 'ref 構造体制約を許可します' は現在、プレビュー段階であり、*サポートされていません*。プレビュー機能を使用するには、'preview' 言語バージョンを使用してください。

追加した例です。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <LangVersion>preview</LangVersion>
  </PropertyGroup>

</Project>

■ 備えよう

.NET 9。備えよう。

.NET 9 で追加された OrderedDictionary を見る

.NET 9 で System.Collections.Generic.OrderedDictionary が追加されたとのことで、見てみましょう。
github.com

■ Dictionary とは何が違うのか

順序が保持される点が違うはずです。OrderedDictionary だけにあるメソッドを見てみると明確です。

var orderdDictTypeMembers = typeof(System.Collections.Generic.OrderedDictionary<string, object>).GetMembers().Select(m=>m.Name).Distinct().Order().ToArray();
var dictTypeMEmbers = typeof(System.Collections.Generic.Dictionary<string, object>).GetMembers().Select(m => m.Name).Distinct().Order().ToArray();
foreach(var name in orderdDictTypeMembers.Except(dictTypeMEmbers).Intersect(orderdDictTypeMembers))
    Console.WriteLine(name);
// GetAt
// IndexOf
// Insert
// RemoveAt
// SetAt

順序を指定して取得/追加/削除/変更がありますね。

OrderedDictionary があると何がうれしいのか

順序も保持する、高速なキーアクセスでの値の取得、両方やらなくちゃならないのがつらいところ......、という場面でうれしいようです。
もし OrderedDictionary がなかったら、順序保持用に List とキーアクセス用に Dictionary、と二重に保持することになるでしょう。そういうコード、何気に書くこと多くあります。

■ 試してみる

Write(Init(new System.Collections.Generic.OrderedDictionary<string, int>()));
Write(Init(new System.Collections.Generic.Dictionary<string, int>()));
// [c, 0]
// [a, 1]
// [b, 2]
// [c, 0]
// [a, 1]
// [b, 2]

{
    var ordered = new System.Collections.Generic.OrderedDictionary<string, int>();
    Init(ordered);
    ordered.Insert(1, "d", 3);
    Write(ordered);
}
// [c, 0]
// [d, 3]
// [a, 1]
// [b, 2]

static IDictionary<string,int> Init(IDictionary<string, int> d) { d.Add("c",0); d.Add("a", 1); d.Add("b", 2); return d; }
static void Write(IDictionary<string, int> d) { foreach (var m in d) Console.WriteLine(m); }

Dictionary でも add した順になっているのでわかりにくいですが、Insert で追加した場所にちゃんと追加されていますね。

■ 速度に違いはあるのか

Orderされている順でキーアクセスの速度に違いが出るのか、雑に動かしてみます。

var ordered = new System.Collections.Generic.OrderedDictionary<string, int> { { "c", 0 }, { "a", 1 }, { "b", 2 } };
Get(ordered, "a");  // 259760
Get(ordered, "b");  // 90231
Get(ordered, "c");  // 89316
Get(ordered, "a");  // 76363
Get(ordered, "b");  // 39622
Get(ordered, "c");  // 106829

static void Get(IDictionary<string,int> dict, string key) {
    var sw = Stopwatch.StartNew();
    for (long i = 0; i < 100000; ++i) _ = dict[key];
    Console.WriteLine(sw.ElapsedTicks);
}

速度を目的に使うことは必要なさそうですね。

備えよう

備えよう

Teams を YouTube ライブ配信できる カスタム ストリーミング アプリ が動作しない

モバイルでは設定できないようです。

カスタム ストリーミング アプリについては以前に記事を書きました。
rksoftware.hatenablog.com

■ モバイルだとどうなるか

アプリの追加で出てきません。
この時点でモバイルだけでは設定できないことがわかります。

PC でアプリの追加だけしておくと

アプリの一覧に出てきます。

しかし、設定をしようとするとぐるぐるから先に進まず設定できません。

■ PC との併用

PC でストリーミングを開始した会議にモバイルで入ると、ストリーミングが継続できます。
具体的な流れはこんな感じです。

  1. PC でカスタムストリーミングアプリを追加する
  2. PC で会議に参加、カスタムストリーミングアプリに YouTube のライブ配信のストリーミング キー、ストリーミング URL を設定してストリーミング開始
  3. YouTube Studio で配信を開始
  4. PC で会議を退出
  5. モバイルで会議に参加
  6. 会議を終了
  7. YouTube Studio で配信を終了

3 ~ 7 の間、配信が継続します。

会議から全員が退出して 0 人になっていても配信は継続されるようです。

■ 具体的なモバイルでの使い方

無理です。PC が必要です。

Teams ってブラウザでも行けたよね?

今回試したら、モバイルのブラウザでは Teams 使えませんでした。

■ PC は必要

人類に PC は必要です。油断せずに持ち歩くようにしましょう。

.NET 9 GeneratedRegex 属性がプロパティで

GeneratedRegex 属性が .NET 9 のプレビュー版でプロパティにつけられるようになっています。

github.com

■ 部分プロパティ

// See https://aka.ms/new-console-template for more information
using System.Text.RegularExpressions;

Console.WriteLine(A.N.IsMatch("1"));    // true
Console.WriteLine(A.N.IsMatch("a"));    // false

static partial class A
{
    //」これは以前からできた
    [GeneratedRegex("\\d")]
    internal static partial Regex M();

    // 部分プロパティに対してできるようになった
    [GeneratedRegex("\\d")]
    internal static partial Regex N { get; }
}

■ 試すために

.csproj ファイルを編集する必要があります。

<LangVersion>preview</LangVersion>

を追加します。これを追加しないと次のエラーになります。

CS8703   C# 12.0 では、修飾子 'partial' はこの項目に対して有効ではありません。'preview' 以上の言語バージョンをご使用ください。

追加した例です。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <LangVersion>preview</LangVersion>
  </PropertyGroup>

</Project>

■ 備えよう

いいですね。.NET 9 期待が高まります。備えよう。