質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.37%

  • C#

    4751questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

C#のStopWatchクラスが上手く実行されない。

解決済

回答 3

投稿 2017/11/30 17:49

  • 評価
  • クリップ 0
  • VIEW 119

shinya551

score 1

前提・実現したいこと

C#のStopWatchクラスを使って正確な時間を計測したい。

発生している問題・エラーメッセージ

ペンタブレットの軌跡情報と一緒に時間も取りたくてStopWatchクラスを使用しました。

実行は出来るのですが、取得している時間が正しくありません。
1秒以上動作させても数ミリ秒程度しか出力されません。
実際に手動で時間を計測したところ2秒のものが4ミリ秒ほどになってしまっています。
以下は実行結果の一部です。カンマ区切りの一番左が時間です。

00:00:00.0000167,455,427,0

00:00:00.0004014,454,452,0

00:00:00.0004126,455,450,0

00:00:00.0004457,456,447,0

00:00:00.0004694,457,444,0

00:00:00.0005223,458,439,0

該当のソースコード

C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Interop;

using WintabNET;

namespace WpfWintabSample
{

/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window
{

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

//StopWacth呼び出し
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

//roop外でoldpress宣言
int oldpress = 0;

// ウインドウプロシージャ
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{

if (msg == (int)EWintabEventMessage.WT_PACKET)
{
WintabPacket packet = WintabManager.GetPacket(lParam, (UInt32)wParam.ToInt32());

sw.Start();//StopWatch(再)スタート

if (packet.pkNormalPressure.pkAbsolutePressure == 0)
{
Point screenPoint = PointToScreen(new Point(0, 0));

int x = (int)(packet.pkX - screenPoint.X);
int y = (int)(packet.pkY - screenPoint.Y);
//int t = sw.Elapsed;
int p = (int)packet.pkNormalPressure.pkAbsolutePressure;

sw.Stop();//StopWatchストップ

if (x != (int)m_Point.X && y != (int)m_Point.Y /*&& oldpress == p*/)
{
//時間、座標、筆圧の書き出し(ペンUP)
Console.WriteLine("{0},{1},{2},{3}\n", sw.Elapsed, x, y, p);
//screenText.Text += + sw.Elapsed + ","+ x + "," + y + "," + p + "\n"; //あとでtを追加
}
//位置保存
m_Point.X = x;
m_Point.Y = y;

}
else
{
Point screenPoint = PointToScreen(new Point(0, 0));

int x = (int)(packet.pkX - screenPoint.X);
int y = (int)(packet.pkY - screenPoint.Y);
int p = (int)packet.pkNormalPressure.pkAbsolutePressure;

sw.Stop();//StopWatchストップ

if (m_Point.X == -1)
{
m_Point.X = x;
m_Point.Y = y;
}
else
{

if (x == (int)m_Point.X && y == (int)m_Point.Y && oldpress == p)
{

//線の追加
addPath((int)m_Point.X, (int)m_Point.Y, x, y, (int)packet.pkNormalPressure.pkAbsolutePressure);

// 位置の保存
m_Point.X = x;
m_Point.Y = y;
oldpress = p;
}
else
{
//時間、座標、筆圧の書き出し(ペンDOWN)
Console.WriteLine("{0},{1},{2},{3}\n", sw.Elapsed, x, y, p);
//screenText.Text += + sw.Elapsed + ","+ x + "," + y + "," + p + "\n";//あとでtを追加

//線の追加
addPath((int)m_Point.X, (int)m_Point.Y, x, y, (int)packet.pkNormalPressure.pkAbsolutePressure);

// 位置の保存
m_Point.X = x;
m_Point.Y = y;
oldpress = p;
}
}
}
}
return IntPtr.Zero;
}

// 線をCanvasに追加する
private void addPath(int x, int y, int x2, int y2, int pressure)
{
Line l = new Line();

// 始点と終点の設定
l.X1 = x;
l.Y1 = y;
l.X2 = x2;
l.Y2 = y2;

// 線のスタイル設定
l.Stroke = Brushes.Black;
l.StrokeStartLineCap = PenLineCap.Round;

// 線の太さは筆圧によって変更する
l.StrokeThickness = (double)pressure / (double)m_MaxPressure * 10.0;

// Canvasへ線を追加
screenCanvas.Children.Add(l);
}

}
}

試したこと

sw.ElapsedMillisecondsでミリ秒単位だけ取得しようとしましたが、
3秒以上実行しても6ミリ秒程しか進みません。

補足情報(言語/FW/ツール等のバージョンなど)

僕のプログラムではなくネットの
WDN技術者(http://blog.wdnet.jp/tech/archives/156)さんのサンプルコードの
addpathというメソッドに直接書き込んでいます。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • SurferOnWww

    2017/11/30 18:10

    コードは ``` と ``` で囲ってください。インデントされて見やすくなりますので。他人に見てもらおうと思うのならそのぐらいの心配りをお願いします。

    キャンセル

回答 3

checkベストアンサー

+2

実際に計測したのはどの部分でしょうか?  
現状のコードでは、StartとStop間に時間のかかりそうな部分もないため、正しい動作のようにも思えます。  

動作タイミングを計測したいのであれば、Stopをかけずに出力でよいのでは?

投稿 2017/11/30 20:42

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/05 13:23

    回答ありがとうございます。
    インデント等見にくく申し訳ありませんでした。
    ペンタブレットで入力している間の時間を計測して座標取得プログラムを1ループするたびにその時の時間を取り出そうと思っていたのですが、どうやらstopwatchクラスの使い方を間違えていたみたいでした。
    結果的に一番最初のstartのすぐ上に2ループ目からstopをかけるようにして、if文の中のstopをかけたあとにすぐstartするようにすることで、継続的に時間を取ることが出来ました。
    僕の力ではstopをかけずに値を取り出す方法が分からなかったため、ちょっと不格好ではありますがこれで時間計測をしていきたいと思います。
    回答ありがとうございました。

    キャンセル

0

インデントがなくてよく分からないのですが、Stop後にもいろいろしているようなので、そこが遅いのではないでしょうか?

投稿 2017/11/30 18:09

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/05 13:27

    回答ありがとうございます。
    インデント等見にくく申し訳ありませんでした。
    どうやら処理が遅かったのではなく、僕のstopのタイミングが悪いみたいでした。
    mituhaさんへのコメントで書きましたがstopとstartを繋げることで、一応は解決いたしました。
    ありがとうございました。

    キャンセル

0

コメント返信だけでは言葉足らずな気がしたので一応コードも載せておきます。
”ずっと計測しつづけたい”とコメントアウトしているものが変更点です。
回答してくださった方はありがとうございました。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'''        //StopWacth呼び出し
'''        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
'''        
'''        //roop外でoldpress宣言
'''        int oldpress = 0;
'''        
'''        //ずっと計測しつづけたい
'''        int i = 0;
'''
'''        // ウインドウプロシージャ
'''        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
'''        {
'''            
'''            if (msg == (int)EWintabEventMessage.WT_PACKET)
'''            {
'''                WintabPacket packet = WintabManager.GetPacket(lParam, (UInt32)wParam.ToInt32());
'''
'''                if (i >= 1)
'''                {
'''                    sw.Stop();//ずっと計測しつづけたい
'''                }
'''
'''                sw.Start();//StopWatch(再)スタート
'''
'''                if (packet.pkNormalPressure.pkAbsolutePressure == 0)
'''                {
'''                    Point screenPoint = PointToScreen(new Point(0, 0));
'''
'''                    int x = (int)(packet.pkX - screenPoint.X);
'''                    int y = (int)(packet.pkY - screenPoint.Y);
'''                    int p = (int)packet.pkNormalPressure.pkAbsolutePressure;
'''
'''                    sw.Stop();//StopWatchストップ
'''                    sw.Start();//ずっと計測しつづけたい
'''
'''                    long t = long sw.Elapsed;
'''
'''                    if (x != (int)m_Point.X && y != (int)m_Point.Y /*&& oldpress == p*/)
'''                    {
'''                        //時間、座標、筆圧の書き出し(ペンUP)
'''                        Console.WriteLine("{0},{1},{2},{3}\n", sw.Elapsed, x, y, p);
'''                    }
'''                    //位置保存
'''                    m_Point.X = x;
'''                    m_Point.Y = y;
'''
'''
'''                }
'''                else
'''                {
'''                    Point screenPoint = PointToScreen(new Point(0, 0));
'''
'''                    int x = (int)(packet.pkX - screenPoint.X);
'''                    int y = (int)(packet.pkY - screenPoint.Y);
'''                    int p = (int)packet.pkNormalPressure.pkAbsolutePressure;
'''
'''                    sw.Stop();//StopWatchストップ
'''                    sw.Start();//ずっと計測しつづけたい
'''
'''                    if (m_Point.X == -1)
'''                    {
'''                        m_Point.X = x;
'''                        m_Point.Y = y;
'''                    }
'''                    else
'''                    {
'''
'''                        if (x == (int)m_Point.X && y == (int)m_Point.Y && oldpress == p)
'''                        {
'''
'''                            //線の追加
'''                            addPath((int)m_Point.X, (int)m_Point.Y, x, y, (int)packet.pkNormalPressure.pkAbsolutePressure);
'''
'''                            // 位置の保存
'''                            m_Point.X = x;
'''                            m_Point.Y = y;
'''                            oldpress = p;
'''                        }
'''                        else
'''                        {
'''                            //時間、座標、筆圧の書き出し(ペンDOWN)
'''                            Console.WriteLine("{0},{1},{2},{3}\n", sw.Elapsed, x, y, p);
'''
'''                            //線の追加
'''                            addPath((int)m_Point.X, (int)m_Point.Y, x, y, (int)packet.pkNormalPressure.pkAbsolutePressure);
'''
'''                            // 位置の保存
'''                            m_Point.X = x;
'''                            m_Point.Y = y;
'''                            oldpress = p;
'''                        }
'''                    }
'''                }
'''
'''                i++;//ずっと計測しつづけたい
'''            }
'''            return IntPtr.Zero;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  

投稿 2017/12/05 14:02

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.37%

関連した質問

同じタグがついた質問を見る

  • C#

    4751questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。